-- ***********************************************
-- * Magashock
-- ***********************************************
--------
function magashock_attack()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "attack")
	local dmgt = Attack.aseq_time(0, "x")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local typedmg=Attack.get_custom_param("typedmg")
	local duration = Attack.get_custom_param("duration")
	Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
	common_cell_apply_damage(target, dmgt+.4)
	effect_magashock(target,dmgt+.4,duration,false)
	Attack.atom_spawn(target, dmgt, "hll_boss_gremlin")
	return true
end

function calccells_magashock()

	if Attack.is_computer_move() then
		local t1,t2,t3,t4,t5,t6 = {},{},{},{},{},{}
		local ai1,ai2 = {},{}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				elseif Attack.act_temporary(ai) then
					table.insert(ai2, ai)
				end
			end
		end
		if table.getn(ai1) == 1 and table.getn(ai2) > 0 then

			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and Attack.act_takesdmg(i)
				and not Attack.act_temporary(i)
				and Attack.act_applicable(i) then
					if (Attack.act_is_spell(i, "effect_mana_explosion")
					or Attack.act_is_spell(i, "effect_mana_explosion2")
					or Attack.act_is_spell(i, "effect_mana_explosion3")
					or Attack.act_is_spell(i, "effect_mana_explosion4")
					or Attack.act_is_spell(i, "effect_mana_explosion5")) then
						table.insert(t1, i)
					elseif Attack.act_get_res(i,"magic") < 0 then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"magic") == 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison") then
						table.insert(t4, i)
					else
						table.insert(t5, i)
					end
				end
			end
		else
			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and not Attack.act_is_spell(i, "spell_phantom")
				and not Attack.act_is_spell(i, "ks_effect_temporary")
				and not Attack.act_is_spell(i, "ks_effect_temporary_ghost")
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					if (Attack.act_is_spell(i, "effect_mana_explosion")
					or Attack.act_is_spell(i, "effect_mana_explosion2")
					or Attack.act_is_spell(i, "effect_mana_explosion3")
					or Attack.act_is_spell(i, "effect_mana_explosion4")
					or Attack.act_is_spell(i, "effect_mana_explosion5")) then
						table.insert(t1, i)
					elseif Attack.act_get_res(i,"magic") < 0 then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"magic") == 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison") then
						table.insert(t4, i)
					else
						table.insert(t5, i)
					end
				elseif (Attack.act_enemy(i) or Attack.act_pawn(i))
				and not Attack.act_ally(i)
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					table.insert(t6, i)
				end
			end
		end
		if table.getn(t1) > 0 then
			for k,v in ipairs(t1) do
				Attack.marktarget(v)
			end
		elseif table.getn(t2) > 0 then
			local tgt = ai_hp_count(t2)
			Attack.marktarget(tgt)
		elseif table.getn(t3) > 0 then
			local tgt = ai_hp_count(t3)
			Attack.marktarget(tgt)
		elseif table.getn(t4) > 0 then
			local tgt = ai_hp_count(t4)
			Attack.marktarget(tgt)
		elseif table.getn(t5) > 0 then
			local tgt = ai_hp_count(t5)
			Attack.marktarget(tgt)
		elseif table.getn(t6) > 0 then
			local tgt = ai_hp_count(t6)
			Attack.marktarget(tgt)
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if (Attack.act_enemy(i) or Attack.act_pawn(i))
			and not Attack.act_ally(i)
			and Attack.act_takesdmg(i)
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end

function effect_magashock(target,pause,duration,dod)

	if pause==nil then
		pause = 1
	end
	if duration==nil then
		duration = tonumber(Logic.obj_par("effect_mana_explosion","duration"))
	end
	if dod==nil then
		dod = true
	end
	if target~=nil then
		if (Attack.act_ally(target)
		or Attack.act_enemy(target))
		and not Attack.act_feature(target,"boss,pawn")
		and not Attack.act_is_spell(target, "effect_mana_explosion5") then

			if Attack.act_is_spell(target, "effect_mana_explosion4") then

				Attack.act_del_spell(target, "effect_mana_explosion4")
				Attack.act_apply_spell_begin(target, "effect_mana_explosion5", duration, dod)
				Attack.act_apply_res_spell("magic", -50, 0, 0, duration, dod)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then

					Attack.log(0.001,"add_blog_mana_explosion5", "name",""..blog_side_unit(target,1))
				end

			elseif Attack.act_is_spell(target, "effect_mana_explosion3") then

				Attack.act_del_spell(target, "effect_mana_explosion3")
				Attack.act_apply_spell_begin(target, "effect_mana_explosion4", duration, dod)
				Attack.act_apply_res_spell("magic", -40, 0, 0, duration, dod)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then

					Attack.log(0.001,"add_blog_mana_explosion4", "name",""..blog_side_unit(target,1))
				end

			elseif Attack.act_is_spell(target, "effect_mana_explosion2") then

				Attack.act_del_spell(target, "effect_mana_explosion2")
				Attack.act_apply_spell_begin(target, "effect_mana_explosion3", duration, dod)
				Attack.act_apply_res_spell("magic", -30, 0, 0, duration, dod)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then

					Attack.log(0.001,"add_blog_mana_explosion3", "name",""..blog_side_unit(target,1))
				end

			elseif Attack.act_is_spell(target, "effect_mana_explosion") then

				Attack.act_del_spell(target, "effect_mana_explosion")
				Attack.act_apply_spell_begin(target, "effect_mana_explosion2", duration, dod)
				Attack.act_apply_res_spell("magic", -20, 0, 0, duration, dod)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then

					Attack.log(0.001,"add_blog_mana_explosion2", "name",""..blog_side_unit(target,1))
				end
			else
				Attack.act_del_spell(target, "effect_mana_explosion")
				Attack.act_del_spell(target, "effect_mana_explosion2")
				Attack.act_del_spell(target, "effect_mana_explosion3")
				Attack.act_del_spell(target, "effect_mana_explosion4")
				Attack.act_del_spell(target, "effect_mana_explosion5")
				Attack.act_apply_spell_begin(target, "effect_mana_explosion", duration, dod)
				Attack.act_apply_res_spell("magic", -10, 0, 0, duration, dod)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then

					Attack.log(0.001,"add_blog_mana_explosion", "name",""..blog_side_unit(target,1))
				end
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Fire Cyclone
-- ***********************************************
--------
function special_fire_cyclone()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local dmgt1,dmgt2=0,0
	local a = Attack.atom_spawn(target, dmgt-.5, "effect_fire_cyclone")
	local dmgt1 = Attack.aseq_time(a, "x")
	local b = Attack.atom_spawn(target, dmgt+.6, "effect_fire_torch")
	dmgt2 = Attack.aseq_time(b, "x")
	local typedmg=Attack.get_custom_param("typedmg")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local fire_res = Attack.act_get_res(target,"fire")
	Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
	common_cell_apply_damage(target, dmgt+dmgt1+dmgt2)
	if not Attack.act_feature(target,"boss,pawn,fire_immunitet")
	and fire_res<80
	and Game.CurLocRand(1,100) <25 then

		effect_burn_attack(target,dmgt+dmgt1+dmgt2+.3,duration,false)

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_burn_2", "targets", ""..blog_side_unit(target,1))
		else
			Attack.log(0.001,"add_blog_burn_1", "target", ""..blog_side_unit(target,1))
		end
	end
	return true
end

function calccells_fire_cyclone()

	if Attack.is_computer_move() then
		local t1,t2,t3,t4,t5,t6 = {},{},{},{},{},{}
		local ai1,ai2 = {},{}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				elseif Attack.act_temporary(ai) then
					table.insert(ai2, ai)
				end
			end
		end
		if table.getn(ai1) == 1 and table.getn(ai2) > 0 then

			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and Attack.act_takesdmg(i)
				and not Attack.act_temporary(i)
				and Attack.act_applicable(i) then
					if Attack.act_feature(i,"plant")
					and Attack.act_get_res(i,"fire") < 0 then
						table.insert(t1, i)
					elseif Attack.act_get_res(i,"fire") < 0 then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"fire") == 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"fire") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"fire") <= Attack.act_get_res(i,"magic")
					and Attack.act_get_res(i,"fire") <= Attack.act_get_res(i,"poison") then
						table.insert(t4, i)
					else
						table.insert(t5, i)
					end
				end
			end
		else
			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and not Attack.act_is_spell(i, "spell_phantom")
				and not Attack.act_is_spell(i, "ks_effect_temporary")
				and not Attack.act_is_spell(i, "ks_effect_temporary_ghost")
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					if Attack.act_feature(i,"plant")
					and Attack.act_get_res(i,"fire") < 0 then
						table.insert(t1, i)
					elseif Attack.act_get_res(i,"fire") < 0 then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"fire") == 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"fire") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"fire") <= Attack.act_get_res(i,"magic")
					and Attack.act_get_res(i,"fire") <= Attack.act_get_res(i,"poison") then
						table.insert(t4, i)
					else
						table.insert(t5, i)
					end
				elseif (Attack.act_enemy(i) or Attack.act_pawn(i))
				and not Attack.act_ally(i)
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					table.insert(t6, i)
				end
			end
		end
		if table.getn(t1) > 0 then
			local tgt = ai_hp_count(t1)
			Attack.marktarget(tgt)
		elseif table.getn(t2) > 0 then
			local tgt = ai_hp_count(t2)
			Attack.marktarget(tgt)
		elseif table.getn(t3) > 0 then
			local tgt = ai_hp_count(t3)
			Attack.marktarget(tgt)
		elseif table.getn(t4) > 0 then
			local tgt = ai_hp_count(t4)
			Attack.marktarget(tgt)
		elseif table.getn(t5) > 0 then
			local tgt = ai_hp_count(t5)
			Attack.marktarget(tgt)
		elseif table.getn(t6) > 0 then
			local tgt = ai_hp_count(t6)
			Attack.marktarget(tgt)
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if (Attack.act_enemy(i) or Attack.act_pawn(i))
			and not Attack.act_ally(i)
			and Attack.act_takesdmg(i)
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * sorcery_embrace
-- ***********************************************
--------
function sorcery_embrace()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "attack")
	local dmgt = Attack.aseq_time(0, "x")
	local hand_time = dmgt
	local hand_move = dmgt+1
	local hand = Attack.atom_spawn(0, dmgt, "effect_sorcery_embrace",Attack.angleto(0,target))
	Attack.act_move(hand_time, hand_move, hand, target)
	local duration = tonumber(Attack.get_custom_param("duration"))
	local level = tonumber(Attack.get_custom_param("level"))
	local power = tonumber(Attack.get_custom_param("power"))
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local typedmg=Attack.get_custom_param("typedmg")
	Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
	common_cell_apply_damage(target, dmgt+1.4)
	effect_devour_magic_attack(target,dmgt+1.4,duration,level,power)
	return true
end

function calccells_sorcery_embrace()

	if Attack.is_computer_move() then
		local t1,t2,t3,t4,t5,t6,t7 = {},{},{},{},{},{},{}
		local ai1,ai2 = {},{}
		local buff = {}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				elseif Attack.act_temporary(ai) then
					table.insert(ai2, ai)
				end
			end
		end
		if table.getn(ai1) == 1 and table.getn(ai2) > 0 then

			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and Attack.act_takesdmg(i)
				and not Attack.act_temporary(i)
				and Attack.act_applicable(i) then
					for k=0,Attack.act_spell_count(i)-1 do
						local spell_name = Attack.act_spell_name(i,k)
						local spell_type = Logic.obj_par(spell_name,"type")
						if spell_type=="bonus"
						and string.find(spell_name,"^totem_")==nil
						and string.find(spell_name,"^ks_effect_")==nil
						and spell_name ~= "spell_slime_glot"
						and spell_name ~= "spell_phantom"
						and spell_name ~= "ks_effect_temporary"
						and spell_name ~= "ks_effect_temporary_ghost" then
							table.insert(buff, spell_name)
							break
						end
					end
					if table.getn(buff) > 0 then
						table.insert(t1, i)
						for k,v in pairs(buff) do
							table.remove(buff)
						end
					elseif Attack.act_is_spell(i, "effect_sorrow")
					or Attack.act_is_spell(i, "effect_sorrow2")
					or Attack.act_is_spell(i, "effect_sorrow3") then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"poison") < 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"poison") == 0 then
						table.insert(t4, i)
					elseif Attack.act_get_res(i,"poison") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"poison") <= Attack.act_get_res(i,"magic")
					and Attack.act_get_res(i,"poison") <= Attack.act_get_res(i,"fire") then
						table.insert(t5, i)
					else
						table.insert(t6, i)
					end
				end
			end
		else
			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and not Attack.act_is_spell(i, "spell_phantom")
				and not Attack.act_is_spell(i, "ks_effect_temporary")
				and not Attack.act_is_spell(i, "ks_effect_temporary_ghost")
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					for k=0,Attack.act_spell_count(i)-1 do
						local spell_name = Attack.act_spell_name(i,k)
						local spell_type = Logic.obj_par(spell_name,"type")
						if spell_type=="bonus"
						and string.find(spell_name,"^totem_")==nil
						and string.find(spell_name,"^ks_effect_")==nil
						and spell_name ~= "spell_slime_glot"
						and spell_name ~= "spell_phantom"
						and spell_name ~= "ks_effect_temporary"
						and spell_name ~= "ks_effect_temporary_ghost" then
							table.insert(buff, spell_name)
							break
						end
					end
					if table.getn(buff) > 0 then
						table.insert(t1, i)
						for k,v in pairs(buff) do
							table.remove(buff)
						end
					elseif Attack.act_is_spell(i, "effect_sorrow")
					or Attack.act_is_spell(i, "effect_sorrow2")
					or Attack.act_is_spell(i, "effect_sorrow3") then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"poison") < 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"poison") == 0 then
						table.insert(t4, i)
					elseif Attack.act_get_res(i,"poison") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"poison") <= Attack.act_get_res(i,"magic")
					and Attack.act_get_res(i,"poison") <= Attack.act_get_res(i,"fire") then
						table.insert(t5, i)
					else
						table.insert(t6, i)
					end
				elseif (Attack.act_enemy(i) or Attack.act_pawn(i))
				and not Attack.act_ally(i)
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					table.insert(t7, i)
				end
			end
		end
		if table.getn(t1) > 0 then
			local tgt = ai_hp_count(t1)
			Attack.marktarget(tgt)
		elseif table.getn(t2) > 0 then
			for k,v in ipairs(t2) do
				Attack.marktarget(v)
			end
		elseif table.getn(t3) > 0 then
			local tgt = ai_hp_count(t3)
			Attack.marktarget(tgt)
		elseif table.getn(t4) > 0 then
			local tgt = ai_hp_count(t4)
			Attack.marktarget(tgt)
		elseif table.getn(t5) > 0 then
			local tgt = ai_hp_count(t5)
			Attack.marktarget(tgt)
		elseif table.getn(t6) > 0 then
			local tgt = ai_hp_count(t6)
			Attack.marktarget(tgt)
		elseif table.getn(t7) > 0 then
			local tgt = ai_hp_count(t7)
			Attack.marktarget(tgt)
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if (Attack.act_enemy(i) or Attack.act_pawn(i))
			and not Attack.act_ally(i)
			and Attack.act_takesdmg(i)
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Holyshock
-- ***********************************************
--------
function holyshock_attack()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "attack")
	local dmgt = Attack.aseq_time(0, "x")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local typedmg=Attack.get_custom_param("typedmg")
	if Attack.act_feature(target,"undead,demon") then
		Attack.atk_set_damage(typedmg,dmg_min*2,dmg_max*2)
	else
		Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
	end
	common_cell_apply_damage(target, dmgt)
	Attack.atom_spawn(target, dmgt, "effect_flash")
	return true
end

function calccells_holyshock()

	if Attack.is_computer_move() then
		local t1,t2,t3,t4,t5,t6,t7 = {},{},{},{},{},{},{}
		local ai1,ai2 = {},{}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				elseif Attack.act_temporary(ai) then
					table.insert(ai2, ai)
				end
			end
		end
		if table.getn(ai1) == 1 and table.getn(ai2) > 0 then

			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and Attack.act_takesdmg(i)
				and not Attack.act_temporary(i)
				and Attack.act_applicable(i) then
					if Attack.act_feature(i,"undead,demon")
					and Attack.act_get_res(i,"magic") < 0 then
						table.insert(t1, i)
					elseif Attack.act_feature(i,"undead,demon") then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"magic") < 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"magic") == 0 then
						table.insert(t4, i)
					elseif Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison") then
						table.insert(t5, i)
					else
						table.insert(t6, i)
					end
				end
			end
		else
			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss")
				and not Attack.act_is_spell(i, "spell_phantom")
				and not Attack.act_is_spell(i, "ks_effect_temporary")
				and not Attack.act_is_spell(i, "ks_effect_temporary_ghost")
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					if Attack.act_feature(i,"undead,demon")
					and Attack.act_get_res(i,"magic") < 0 then
						table.insert(t1, i)
					elseif Attack.act_feature(i,"undead,demon") then
						table.insert(t2, i)
					elseif Attack.act_get_res(i,"magic") < 0 then
						table.insert(t3, i)
					elseif Attack.act_get_res(i,"magic") == 0 then
						table.insert(t4, i)
					elseif Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison") then
						table.insert(t5, i)
					else
						table.insert(t6, i)
					end
				elseif (Attack.act_enemy(i) or Attack.act_pawn(i))
				and not Attack.act_ally(i)
				and Attack.act_takesdmg(i)
				and Attack.act_applicable(i) then
					table.insert(t7, i)
				end
			end
		end
		if table.getn(t1) > 0 then
			local tgt = ai_hp_count(t1)
			Attack.marktarget(tgt)
		elseif table.getn(t2) > 0 then
			local tgt = ai_hp_count(t2)
			Attack.marktarget(tgt)
		elseif table.getn(t3) > 0 then
			local tgt = ai_hp_count(t3)
			Attack.marktarget(tgt)
		elseif table.getn(t4) > 0 then
			local tgt = ai_hp_count(t4)
			Attack.marktarget(tgt)
		elseif table.getn(t5) > 0 then
			local tgt = ai_hp_count(t5)
			Attack.marktarget(tgt)
		elseif table.getn(t6) > 0 then
			local tgt = ai_hp_count(t6)
			Attack.marktarget(tgt)
		elseif table.getn(t7) > 0 then
			local tgt = ai_hp_count(t7)
			Attack.marktarget(tgt)
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if (Attack.act_enemy(i) or Attack.act_pawn(i))
			and not Attack.act_ally(i)
			and Attack.act_takesdmg(i)
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Hymn
-- ***********************************************
--------
function special_hymn()

	local farest_dist, farest_enemy, ang_to_enemy = 0e0, nil, 0

	for k=1,Attack.act_count()-1 do

		if Attack.act_enemy(k) then
			local d = Attack.cell_dist(0,k)

			if d > farest_dist then farest_dist = d; farest_enemy = k; end
		end
	end

	if farest_enemy ~= nil then ang_to_enemy = farest_enemy end
	Attack.aseq_rotate(0, ang_to_enemy, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local count = Attack.act_size(0)
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	local n = Attack.cell_count()
	for j=0,n-1 do

		local i = Attack.cell_get(j)
		local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
		local typedmg = Attack.get_custom_param("typedmg")
		local duration = tonumber(Attack.get_custom_param("duration"))

		if Attack.act_enemy(i)
		and not Attack.act_feature(i,"pawn") then

			Attack.atom_spawn(i, dmgt-.5, "effect_hymn")

			if Attack.act_feature(i,"undead,demon") then

				Attack.atk_set_damage(typedmg,dmg_min*3,dmg_max*3)
				common_cell_apply_damage(i,dmgt)
				effect_hymn_attack(i,dmgt,duration)
			else
				Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
				common_cell_apply_damage(i,dmgt)
			end
  		end
	end

	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end

function calccells_hymn()

	if Attack.is_computer_move() then
		local udcount,uicount = {},{}
		for k=1,Attack.act_count()-1 do

			if Attack.act_enemy(k)
			and Attack.act_feature(k,"undead,demon") then
				table.insert(udcount, k)
			elseif Attack.act_enemy(k)
			and not Attack.act_feature(k,"pawn,boss,magic_immunitet") then
				table.insert(uicount, k)
			end

		end
		if table.getn(udcount) > 2 then
			Attack.multiselect(0)
		elseif table.getn(uicount) > 4 then
			Attack.multiselect(0)
		end
	else
		Attack.multiselect(0)
	end
	return true
end

function effect_hymn_attack(target,pause,duration,power)


	if pause==nil then
		pause=0
	end
	if duration==nil then
		duration=tonumber(Logic.obj_par("effect_hymn","duration"))
	end
	if power==nil then
		power=tonumber(Logic.obj_par("effect_hymn","power"))
	end
	if target==nil then
		target = Attack.get_target()
	end

	Attack.act_del_spell( target, "effect_holy" )
	Attack.act_del_spell( target, "effect_hymn" )
	Attack.act_apply_spell_begin(target, "effect_hymn", duration, false )
	Attack.act_apply_par_spell("attack", 0, -power, 0, duration, false)
 	Attack.act_apply_par_spell("defense", 0, -power, 0, duration, false)
 	Attack.act_apply_par_spell("initiative", 0, -power, 0, duration, false)
	Attack.act_apply_spell_end()
	Attack.act_damage_addlog(target,"add_blog_holy_")
	Attack.atom_spawn(target, pause, "effect_purification",0,true)
	return true
end
--------
-- ***********************************************
-- * Salvation One Only
-- ***********************************************
--------
function special_salvation_one()

	local target = Attack.get_target()
	local cotarget = Attack.cell_get_corpse(target)
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local dmgt1,dmgt2,dmgt3= 0,0,0
	local debuff={}

	if (target ~= nil) then

		local a = Attack.atom_spawn(target, dmgt, "hll_priest_heal_post")
		dmgt1 = Attack.aseq_time(a, "x")
		local power = tonumber(Attack.get_custom_param("heal"))
		local heal = math.floor(power*Attack.act_size(0))*(1+tonumber(skill_power2("resurrection",2)/100))
		local mp_lv = tonumber(Attack.val_restore(0,"mana_lv"))

		if mp_lv==2 then
			heal = heal*1.5
		elseif mp_lv==3 then
			heal = heal*2
		end

		local c = Attack.atom_spawn(target, dmgt+dmgt1, "effect_total_cure")
		local count = tonumber(Attack.act_size(target))
		dmgt3=Attack.aseq_time(c, "x")

		if Attack.cell_is_empty(target)
		and Attack.cell_has_ally_corpse(target) then

			local n = tonumber(Attack.act_initsize(cotarget)*Attack.act_get_par(cotarget,"health"))
			if n < heal then
				heal = n
			end

			heal = math.floor(heal)
			Attack.cell_resurrect(cotarget, heal, dmgt-.2)
			Attack.act_cure(target, -heal, dmgt+dmgt3)
		else
			local n = tonumber(Attack.act_initsize(target)*Attack.act_get_par(target,"health") - Attack.act_totalhp(target))
			local type = "penalty"

			if n < heal then
				heal = n
			end

			heal = math.floor(heal)
			Attack.cell_resurrect(target, heal, dmgt+dmgt3)
			Attack.act_cure(target, -heal, dmgt+dmgt3)

			for i=0,Attack.act_spell_count(target)-1 do

				local spell_name = Attack.act_spell_name(target,i)
				local spell_type = Logic.obj_par(spell_name,"type")

				if spell_type==type
				and string.find(spell_name,"^totem_")==nil
				and string.find(spell_name,"^ks_effect_")==nil
				and spell_name ~= "spell_slime_glot"
				and spell_name ~= "spell_phantom"
				and not Attack.act_is_spell(target, "effect_counterspell") then
					table.insert(debuff, spell_name)
				end
			end

			if table.getn(debuff) > 0 then
				takeoff_spells(target, type)
			end
		end

		count = tonumber(Attack.act_size(target)) - count
		if count == 0 then
			Attack.log(0.001,"add_blog_salvation_cure", "targets",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1), "special",""..heal)
		else
			Attack.log(0.001,"add_blog_salvation_resr", "targets",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1), "special",""..heal, "special2",""..count)
		end
		if table.getn(debuff) > 0 then
			Attack.log(0.001,"add_blog_remove_debuff_gaea", "name",""..blog_side_unit(target,1))
		end
	end
	return true
end

function calccells_all_cure_or_resurrect_ally()

	local n = Attack.cell_count()
	for i=0,n-1 do

		local cell = Attack.cell_get(i)
		local cocell = Attack.cell_get_corpse(cell)

		if Attack.cell_is_empty(cell)
		and Attack.cell_has_ally_corpse(cell)
		and Attack.cell_need_resurrect(cell)
		and not (Attack.act_feature(cocell,"undead,demon,golem,mech,pawn,boss")
		or Attack.act_name(cocell)=="griffin_spirit")
		and Attack.act_applicable(cocell) then

			Attack.marktarget(cell)

		elseif Attack.act_ally(cell)
		and (Attack.act_need_cure(cell) or Attack.cell_need_resurrect(cell))
		and not (Attack.act_feature(cell,"undead,demon,golem,mech,pawn,boss") or Attack.act_name(cell)=="griffin_spirit")
		and Attack.act_applicable(cell) then

			Attack.marktarget(cell)

		else
			for k=0,Attack.act_spell_count(cell)-1 do

				local spell_name = Attack.act_spell_name(cell,k)
				local spell_type = Logic.obj_par(spell_name,"type")
				local type = "penalty"

				if Attack.act_ally(cell)
				and spell_type==type
				and not (Attack.act_feature(cell,"undead,demon,golem,mech,pawn,boss") or Attack.act_name(cell)=="griffin_spirit")
				and Attack.act_applicable(cell) then

					Attack.marktarget(cell)
				end
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Salvation
-- ***********************************************
--------
function special_salvation()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local dmgt1,dmgt2,dmgt3 = 0,0,0
	if (target ~= nil) then

		local a = Attack.atom_spawn(target, dmgt, "effect_lightpower")
		dmgt1 = Attack.aseq_time(a, "x")

		local n = Attack.cell_count()
		for j=0,n-1 do

			local i = Attack.cell_get(j)
			if Attack.cell_dist(target,i) <=1 then

				local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("power"))
				local typedmg=Attack.get_custom_param("typedmg")

				if Attack.act_feature(i,"undead,demon") then

					local b = Attack.atom_spawn(i, dmgt+dmgt1, "effect_hard_bless")
					dmgt2 = Attack.aseq_time(b, "x")

					Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
					common_cell_apply_damage(i,dmgt+dmgt2)

				elseif (Attack.act_need_cure(i)
				or (Attack.cell_need_resurrect(i)
				and not Attack.cell_is_empty(i)))
				and not (Attack.act_feature(i,"golem,mech")
				or Attack.act_name(i)=="griffin_spirit") then

					local heal = math.floor(Game.CurLocRand(dmg_min*Attack.act_size(0),dmg_max*Attack.act_size(0)))*(1+tonumber(skill_power2("resurrection",2)/100))
					local need = Attack.act_initsize(i)*Attack.act_get_par(i,"health") - Attack.act_totalhp(i)

					if need < 0 then
						need = Attack.act_get_par(i,"health") - Attack.act_hp(i)
					end

					heal = math.min(need, heal)

					local c = Attack.atom_spawn(i, dmgt+dmgt1, "effect_total_cure")
					local count=Attack.act_size(i)
					dmgt3=Attack.aseq_time(c, "x")

					if need > 0 then
						Attack.cell_resurrect(i, heal, dmgt+dmgt3)
						Attack.act_cure(i, -heal, dmgt+dmgt3)
					else
						Attack.act_cure(i, heal, dmgt+dmgt3)
					end


					local d, label, slabel = Attack.act_size(i) - count
					if Attack.act_size(i)>1 then
						slabel = "2"
					else
						slabel = "1"
					end
					if d > 0 then
						label = "add_blog_res_";
						heal = d
					else
						label = "add_blog_cure_"
					end

					Attack.log(0.001, label..slabel, "target",blog_side_unit(i,0),"special",heal)
				end
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Blasphemous One Only
-- ***********************************************
--------
function special_blasphemous_one()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local a = Attack.atom_spawn(target, dmgt, "effect_blasphemous")
	local dmgt1 = Attack.aseq_time(a, "x")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local typedmg = Attack.get_custom_param("typedmg")
	local mp_lv = tonumber(Attack.val_restore(0,"mana_lv"))
	local k = Attack.get_custom_param("lv1")
	if mp_lv==2 then
		k = Attack.get_custom_param("lv2")
	elseif mp_lv==3 then
		k = Attack.get_custom_param("lv3")
	end
	if Attack.act_feature(target,"holy,humanoid,demon") then
		Attack.atk_set_damage(typedmg,dmg_min*1.2,dmg_max*1.2)
	elseif not (Attack.act_feature(target,"golem,mech,undead,pawn,boss")
	or Attack.act_name(target)=="griffin_spirit") then
		Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
	else
		Attack.atk_set_damage(typedmg,dmg_min*.5,dmg_max*.5)
	end
	common_cell_apply_damage(target, dmgt+dmgt1)
	local dmg = math.min(Attack.act_totalhp(target), (Attack.act_damage_results(target)))
	dmg = math.floor(dmg*k/100)
	if not (Attack.act_feature(target,"golem,mech,undead,pawn,boss")
	or Attack.act_name(target)=="griffin_spirit") then
  		local b = Attack.atom_spawn(0, dmgt+dmgt1, "effect_total_cure")
  		local dmgt2 = Attack.aseq_time(b, "x")
		local count = tonumber(Attack.act_size(0))
		Attack.cell_resurrect(0, dmg, dmgt+dmgt1+dmgt2)
		Attack.act_cure(0, -dmg, dmgt+dmgt1+dmgt2)
		count = Attack.act_size(0) - count
		if count == 0 then
			Attack.log(0.001,"add_blog_lifedrain_cure", "targets",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1), "special",""..dmg)
		else
			Attack.log(0.001,"add_blog_lifedrain_resr", "targets",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1), "special",""..dmg, "special2",""..count)
		end
	end 
	return true
end

function calccells_blasphemous_one()

	if Attack.is_computer_move() then
		local passcount = {}
		for k=1,Attack.act_count()-1 do
			if Attack.act_enemy(k)
			and not Attack.act_feature(k,"golem,mech,undead,pawn,boss") then
				table.insert(passcount, k)
			end
		end
		if table.getn(passcount) == 0 then
			local t1,t2,t3= {},{},{}
			for c=0,Attack.cell_count()-1 do
				local i = Attack.cell_get(c)
				if Attack.act_enemy(i)
				and Attack.act_applicable(i) then
					if Attack.act_get_res(i,"magic") < 0 then
						table.insert(t1, i)
					elseif Attack.act_get_res(i,"magic") == 0 then
						table.insert(t2, i)
					elseif (Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
					and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison")) then
						table.insert(t3, i)
					end
				end
			end
			if table.getn(t1) > 0 then
				local tgt = ai_hp_count(t1)
				Attack.marktarget(tgt)
			elseif table.getn(t2) > 0 then
				local tgt = ai_hp_count(t2)
				Attack.marktarget(tgt)
			elseif table.getn(t3) > 0 then
				local tgt = ai_hp_count(t3)
				Attack.marktarget(tgt)
			end
		elseif table.getn(passcount) > 0 then
			local power = Attack.act_size(0)
			local hp = Attack.act_get_par(0,"health")
			local loss1 = Attack.act_initsize(0) - power
			local loss2 = hp - Attack.act_hp(0)
			local need = (loss1*hp) + loss2
			local mp_lv = tonumber(Attack.val_restore(0,"mana_lv"))
			local k = Attack.get_custom_param("lv1")
			if mp_lv==2 then
				k = Attack.get_custom_param("lv2")
			elseif mp_lv==3 then
				k = Attack.get_custom_param("lv3")
			end
			local heal = tonumber(Attack.get_custom_param("heal"))*power*k*.01
			if need > heal then
				local t1,t2,t3,t4,t5,t6= {},{},{},{},{},{}
				for c=0,Attack.cell_count()-1 do
					local i = Attack.cell_get(c)
					if Attack.act_enemy(i)
					and not Attack.act_feature(i,"golem,mech,undead,pawn,boss")
					and Attack.act_applicable(i) then
						if Attack.act_feature(i,"holy,humanoid,demon")
						and Attack.act_get_res(i,"magic") < 0 then
							table.insert(t1, i)
						elseif Attack.act_feature(i,"holy,humanoid,demon")
						and Attack.act_get_res(i,"magic") == 0 then
							table.insert(t2, i)
						elseif Attack.act_feature(i,"holy,humanoid,demon")
						and (Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
						and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
						and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison")) then
							table.insert(t3, i)
						elseif Attack.act_get_res(i,"magic") < 0 then
							table.insert(t4, i)
						elseif Attack.act_get_res(i,"magic") == 0 then
							table.insert(t5, i)
						elseif (Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"physical")
						and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"fire")
						and Attack.act_get_res(i,"magic") <= Attack.act_get_res(i,"poison")) then
							table.insert(t6, i)
						end
					end
				end
				if table.getn(t1) > 0 then
					local tgt = ai_lv_count(t1)
					Attack.marktarget(tgt)
				elseif table.getn(t2) > 0 then
					local tgt = ai_lv_count(t2)
					Attack.marktarget(tgt)
				elseif table.getn(t3) > 0 then
					local tgt = ai_lv_count(t3)
					Attack.marktarget(tgt)
				elseif table.getn(t4) > 0 then
					local tgt = ai_lv_count(t4)
					Attack.marktarget(tgt)
				end
			end
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if Attack.act_enemy(i)
			and Attack.act_takesdmg(i)
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Blasphemous
-- ***********************************************
--------
function special_blasphemous()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local dmgt1,dmgt2,dmgt3=0,0,0
	local k = Attack.get_custom_param("lv2")
	if (target ~= nil) then

		local a = Attack.atom_spawn(target, dmgt, "effect_mana_explosion")
		dmgt1 = Attack.aseq_time(a, "x")

		local n = Attack.cell_count()
		local drain = 0
		for j=0,n-1 do

			local i = Attack.cell_get(j)
			if Attack.cell_dist(target,i) <=1 then

				local duration = Attack.get_custom_param("duration")
				local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
				local typedmg=Attack.get_custom_param("typedmg")
				local dmg,hp,result

				if Attack.act_feature(i,"holy,humanoid,demon") then

					Attack.atk_set_damage(typedmg,dmg_min*1.2,dmg_max*1.2)
					common_cell_apply_damage(i,dmgt+dmgt1)
					hp = Attack.act_totalhp(i)
					result = Attack.act_damage_results(i)
					if result ==nil then result = 0 end
					dmg = math.min(hp, result)
					drain = drain + dmg

				elseif not (Attack.act_feature(i,"golem,mech,undead,pawn,boss")
				or Attack.act_name(i)=="griffin_spirit") then

					Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
					common_cell_apply_damage(i,dmgt+dmgt1)
					hp = Attack.act_totalhp(i)
					result = Attack.act_damage_results(i)
					if result ==nil then result = 0 end
					dmg = math.min(hp, result)
					drain = drain + dmg
				else
					Attack.atk_set_damage(typedmg,dmg_min*.5,dmg_max*.5)
					common_cell_apply_damage(i,dmgt+dmgt1)
				end
			end
		end

		if drain > 0 then

  			local b = Attack.atom_spawn(0, dmgt+dmgt1, "effect_total_cure")
  			local dmgt2 = Attack.aseq_time(b, "x")
			drain = math.floor(drain*k/100)
			local count = tonumber(Attack.act_size(0))
			Attack.cell_resurrect(0, drain, dmgt+dmgt1+dmgt2)
			Attack.act_cure(0, -drain, dmgt+dmgt1+dmgt2)
			count = Attack.act_size(0) - count

			if count == 0 then
				Attack.log(0.001,"add_blog_lifedrain2_cure","name",""..blog_side_unit(0,1), "special",""..drain)
			else
				Attack.log(0.001,"add_blog_lifedrain2_resr","name",""..blog_side_unit(0,1), "special",""..drain, "special2",""..count)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Evil Scream
-- ***********************************************
--------
function special_evil_scream()

	local farest_dist, farest_enemy, ang_to_enemy = 0e0, nil, 0

	for k=1,Attack.act_count()-1 do

		if Attack.act_enemy(k) then
			local d = Attack.cell_dist(0,k)

			if d > farest_dist then farest_dist = d; farest_enemy = k; end
		end
	end

	if farest_enemy ~= nil then ang_to_enemy = farest_enemy end
	Attack.aseq_rotate(0, ang_to_enemy, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local count = Attack.act_size(0)
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	local n = Attack.cell_count()
	for j=0,n-1 do

		local i = Attack.cell_get(j)
		local duration = tonumber(Attack.get_custom_param("duration"))
		local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
		local typedmg=Attack.get_custom_param("typedmg")

		if Attack.act_enemy(i)
		and not Attack.act_feature(i,"pawn") then

			if Attack.act_feature(i,"holy") then

				Attack.atk_set_damage(typedmg,dmg_min*1.5,dmg_max*1.5)

			elseif (Attack.act_feature(i,"undead,plant,golem,mech")
			or Attack.act_name(i)=="griffin_spirit") then

				Attack.atk_set_damage(typedmg,dmg_min/2,dmg_max/2)
			else
				Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
			end

			Attack.atom_spawn(i, dmgt, "effect_nightmare")
			common_cell_apply_damage(i,dmgt+.5)

			if not (Attack.act_feature(i,"undead,plant,golem,mech,mind_immunitet,boss")
			or Attack.act_name(i)=="griffin_spirit") then

				if (Game.CurLocRand(1,100) <80 and Attack.act_feature(i,"holy"))
				or (Game.CurLocRand(1,100) <20 and Attack.act_level(i)==5)
				or (Game.CurLocRand(1,100) <33 and Attack.act_level(i)==4)
				or (Game.CurLocRand(1,100) <50 and Attack.act_level(i)<4) then
					effect_sleep_attack(i,dmgt+.5,duration+1,false)
					if Attack.act_size(i)>1 then
						Attack.log(0.001,"add_blog_sleep_2", "targets", ""..blog_side_unit(i,1))
					else
						Attack.log(0.001,"add_blog_sleep_1", "target", ""..blog_side_unit(i,1))
					end
				end
			end
  		end
	end

	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)

	return true
end

function calccells_evil_scream()

	if Attack.is_computer_move() then
		local hdcount,uicount = {},{}
		for k=1,Attack.act_count()-1 do

			if Attack.act_enemy(k)
			and Attack.act_feature(k,"holy,humanoid,demon") then
				table.insert(hdcount, k)
			elseif Attack.act_enemy(k)
			and not (Attack.act_feature(k,"undead,plant,golem,mech,pawn,boss")
			or Attack.act_name(k)=="griffin_spirit") then
				table.insert(uicount, k)
			end
		end
		if table.getn(hdcount) > 2 then
			Attack.multiselect(0)
		elseif table.getn(uicount) > 4 then
			Attack.multiselect(0)
		end
	else
		Attack.multiselect(0)
	end
	return true
end
--------
-- ***********************************************
-- * Sorcery Swamp
-- ***********************************************
--------
function special_sorcery_swamp()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local dmgt1,dmgt2,dmgt3=0,0,0
	if (target ~= nil) then

		local a = Attack.atom_spawn(target, dmgt-.3, "effect_sorcery_swamp")
		dmgt1 = Attack.aseq_time(a, "x")

		local n = Attack.cell_count()
		for j=0,n-1 do

			local i = Attack.cell_get(j)
			if Attack.cell_dist(target,i) <=1 then

				if (Attack.act_ally(i)
				or Attack.act_enemy(i))
				and not Attack.act_feature(i,"mech,pawn") then

					local duration = Attack.get_custom_param("duration")
					local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
					local typedmg=Attack.get_custom_param("typedmg")

					if (Attack.act_ally(i)
					or Attack.act_enemy(i))
					and not (Attack.act_feature(i,"undead,golem")
					or Attack.act_name(i)=="griffin_spirit") then

						Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
						effect_sorcery_swamp(i,dmgt+dmgt1,duration,false)

						if Game.CurLocRand(1,100) <50
						and not Attack.act_feature(i,"poison_immunitet")
						and not Attack.act_name(i)=="troll" then

							effect_poison_attack(i,dmgt+dmgt1,duration,0)
						else
							dmgt2=0
						end

					else
						Attack.atk_set_damage(typedmg,dmg_min/200,dmg_max/200)
						effect_sorcery_swamp(i,dmgt+dmgt1,duration,false)
					end

					common_cell_apply_damage(i,dmgt+dmgt1+dmgt2)
				end
			end
		end
	end
	return true
end

function effect_sorcery_swamp(target,pause,duration,dod)

	if pause==nil then
		pause = 1
	end
	if duration==nil then
		duration = tonumber(Logic.obj_par("effect_sorcery_swamp","duration"))
	end
	if dod==nil then
		dod = true
	end
	if target~=nil then

		if (Attack.act_ally(target)
		or Attack.act_enemy(target))
		and not Attack.act_feature(target,"boss,pawn")
		and not Attack.act_is_spell(target, "effect_sorcery_swamp") then

			Attack.act_del_spell(target, "effect_sorcery_swamp")
			Attack.act_apply_spell_begin(target, "effect_sorcery_swamp", duration, dod)
			Attack.act_apply_res_spell("poison", -25, 0, 0, duration, dod)
			Attack.act_apply_spell_end()

			if Attack.act_size(target)>1 then

				Attack.log(0.001,"add_blog_sorcery_swamp", "name",""..blog_side_unit(target,1))
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Acid Cloud
-- ***********************************************
--------
function special_acidcloud()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local power = tonumber(Attack.act_size(0))
	local time = tonumber(Attack.get_custom_param("time"))
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end

	for act=1, Attack.act_count()-1 do
		if Attack.act_name(act) == "acidcloud" then
			for i=0,Attack.act_attach(act)-1 do
				Attack.act_remove(Attack.act_attach(act, i), 0)
			end
			Attack.act_remove(act, 0)
		end
	end

	local atom = Attack.atom_spawn(target,dmgt,"acidcloud")
	Attack.val_store(atom, "power", power)
	Attack.val_store(atom, "cloud_time", time)
	call_acidrains(atom, target, dmgt+.5)
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end

function calccells_acidcloud()

	local calcloud = {}
	for k=1, Attack.act_count()-1 do
		if Attack.act_name(k) == "acidcloud" then
			table.insert(calcloud, k)
		end
	end
	if table.getn(calcloud) < 1 then
		if Attack.is_computer_move() then
			local ai1,ai2 = {},{}
			for ai=1,Attack.act_count()-1 do
				if Attack.act_enemy(ai)
				and not Attack.act_feature(ai,"pawn,boss") then
					if not Attack.act_temporary(ai) then
						table.insert(ai1, ai)
					elseif Attack.act_temporary(ai) then
						table.insert(ai2, ai)
					end
				end
			end
			local bel = Attack.act_belligerent(0)
			if bel == 0 or bel == 4 then
				if table.getn(ai1) == 1 and table.getn(ai2) > 0 then return ture end
			end
			local t1,t2,t3,t4,t5 = {},{},{},{},{}
			for k=0,Attack.cell_count()-1 do
				local count = 0
				local cell = Attack.cell_get(k)
				if Attack.act_enemy(cell) then
					count = count + 1
					for dir=0,5 do
						local d = Attack.cell_adjacent(cell, dir)
						if Attack.act_ally(d) then
							count = -8
						elseif Attack.act_enemy(d) then
							count = count + 1
						end
					end
					if count >= 7 then
						table.insert(t1, cell)
					elseif count >= 6 then
						table.insert(t2, cell)
					elseif count >= 5 then
						table.insert(t3, cell)
					elseif count >= 4 then
						table.insert(t4, cell)
					elseif count >= 3 then
						table.insert(t5, cell)
					end
				elseif (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
					for dir=0,5 do
						local d = Attack.cell_adjacent(cell, dir)
						if Attack.act_ally(d) then
							count = -8
						elseif Attack.act_enemy(d) then
							count = count + 1
						end
					end
					if count >= 7 then
						table.insert(t1, cell)
					elseif count >= 6 then
						table.insert(t2, cell)
					elseif count >= 5 then
						table.insert(t3, cell)
					elseif count >= 4 then
						table.insert(t4, cell)
					elseif count >= 3 then
						table.insert(t5, cell)
					end
				end
			end
			if table.getn(t1) > 0 then
				local tgt = ai_hp_count_mass7(t1)
				Attack.marktarget(tgt)
			elseif table.getn(t2) > 0 then
				local tgt = ai_hp_count_mass7(t2)
				Attack.marktarget(tgt)
			elseif table.getn(t3) > 0 then
				local tgt = ai_hp_count_mass7(t3)
				Attack.marktarget(tgt)
			elseif table.getn(t4) > 0 then
				local tgt = ai_hp_count_mass7(t4)
				Attack.marktarget(tgt)
			elseif table.getn(t5) > 0 then
				local tgt = ai_hp_count_mass7(t5)
				Attack.marktarget(tgt)
			end
		else
			Attack.multiselect(7)
			for i=0,Attack.cell_count()-1 do
				local cell = Attack.cell_get(i)
				if Attack.cell_is_pass(cell) or Attack.get_caa(cell) ~= nil then
					Attack.marktarget(cell, false)
				end
			end
		end
	end
	return true
end

function acidcloud_selmove_atk()
	return Attack.change_attack(0)
end

function acidcloud_selmove()
	return Attack.change_attack(1)
end

function acidcloud_move()
	return true
end

function acidcloud_storm()

	Attack.log_label('null')
	local time = Attack.val_restore("cloud_time")
	if time == nil then time = 1 end
	if time <= 0 then
		local t = Attack.aseq_time(0) + .2
		for k=0,Attack.act_attach(0)-1 do
			Attack.act_remove(Attack.act_attach(0, k), t)
		end
		Attack.act_remove(0, t)
		return true
	end

	local act = Attack.get_cell(0)
	local duration = Attack.get_custom_param("duration")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local typedmg=Attack.get_custom_param("typedmg")
	local power = Attack.val_restore(0,"power")
	local pause = 1
	local found = nil
	local maxcount = 0

	for k=0,Attack.cell_count()-1 do
		local count = 0
		local cell = Attack.cell_get(k)
		if Attack.act_human(cell) or Attack.act_nonhuman(cell) then
			count = 1.5
		end
		for j=0,Attack.cell_count()-1 do
			local c = Attack.cell_get(j)
			if Attack.act_human(c) or Attack.act_nonhuman(c) then
				if Attack.cell_dist(cell,c) == 1 then
					count = count + 1
				elseif Attack.cell_dist(cell,c) == 2 then
					count = count + 1
				end
			end
		end
		if count > maxcount then
			found = cell
			maxcount = count
		end
	end

	if found ~= nil and Attack.cell_id(found) ~= Attack.cell_id(act) then
		local dir = Game.Ang2Dir(Attack.angleto(0, found))
		local cell = Attack.cell_adjacent(0, dir)
		if Attack.cell_present(cell) then
			Attack.act_move(0, pause, 0, cell)
			call_acidrains(0, cell, pause)
			act = cell
		end
	end

	Attack.atk_set_damage(typedmg,dmg_min*power,dmg_max*power)

	for j=0,Attack.cell_count()-1 do

		local i = Attack.cell_get(j)
		if Attack.cell_dist(act,i) <=1
		and Attack.cell_present(i) then

			common_cell_apply_damage(i, pause)
			was_damage = true
		end
	end

	if was_damage then Attack.log_label("") else Attack.log_label("null") end
	if was_damage then time = time - 1 end
	Attack.val_store(0,"cloud_time", time)
	return true
end

function call_acidrains(atom, act, pause)

	local acnt = Attack.act_attach(atom)
	for i=0,acnt-1 do
		Attack.act_remove(Attack.act_attach(atom, i), pause)
	end

	for dir=0,5 do
		local c = Attack.cell_adjacent(act, dir)
		if Attack.cell_present(c) then
			local subatom = Attack.atom_spawn(c,pause,"acidrains")
			Attack.act_attach(atom, subatom, pause+0.001)
		end
	end

	if Attack.cell_present(act) then
		local subatom = Attack.atom_spawn(act,pause,"acidrains")
		Attack.act_attach(atom, subatom, pause+0.001)
	end
end
--------
-- ***********************************************
-- * Maga Gravitational Field
-- ***********************************************
--------
function special_maga_gravitational_field()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local dmgt1,dmgt2,dmgt3=0,0,0
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	if (target ~= nil) then

		local a = Attack.atom_spawn(target, dmgt, "effect_gravitational_field")
		dmgt1 = Attack.aseq_time(a, "x")

		local n = Attack.cell_count()
		for j=0,n-1 do

			local tgt = Attack.cell_get(j)
			if Attack.cell_dist(target,tgt) <=1 then

				local duration = Attack.get_custom_param("duration")
				local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
				local typedmg=Attack.get_custom_param("typedmg")
				if Attack.act_takesdmg(tgt)
				and ((Attack.act_temporary(tgt) or Attack.act_is_spell(tgt, "spell_phantom"))
				or (Game.CurLocRand(1,100) <5 and Attack.act_level(tgt)==5)
				or (Game.CurLocRand(1,100) <10 and Attack.act_level(tgt)==4)
				or (Game.CurLocRand(1,100) <20 and Attack.act_level(tgt)==3)
				or (Game.CurLocRand(1,100) <30 and Attack.act_level(tgt) < 3)) then
					local c = Attack.atom_spawn(tgt, dmgt+dmgt1+2, "hll_post_archmage_lighting")
					dmgt2 = Attack.aseq_time(c, "x");
					effect_paralysis_attack(tgt,dmgt+dmgt1+dmgt2,duration,false)
					if Attack.act_size(tgt)>1 then
						Attack.log(0.001,"add_blog_paralysis", "name",""..blog_side_unit(tgt,1))
					end
				end
				if (Attack.act_temporary(tgt) or Attack.act_is_spell(tgt, "spell_phantom")) then
					Attack.atk_set_damage(typedmg,dmg_min*2,dmg_max*2)
				else
					Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
				end
				common_cell_apply_damage(tgt,dmgt+dmgt1)
			end
		end
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end

function effect_paralysis_attack(target,pause,duration,dod)

	if pause==nil then
		pause = 1
	end
	if duration==nil then
		duration = tonumber(Logic.obj_par("effect_paralysis","duration"))
	end
	if dod==nil then
		dod = true
	end
	if target~=nil then
		if (Attack.act_ally(target) or Attack.act_enemy(target)) and not Attack.act_feature(target,"boss,pawn") then
			Attack.act_apply_spell_begin(target, "effect_paralysis", duration, dod)
			Attack.act_apply_par_spell("skipmove", 1, 0, 0, duration)
			Attack.act_apply_par_spell("hitback", 0, 0, -100, duration, false, 1000)
			Attack.act_apply_spell_end()
		end
	end
	return true
end
--------
-- ***********************************************
-- * Magma Blast
-- ***********************************************
--------
function special_magma_blast()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	if (target ~= nil) then
		local subtargets = {}
		for k=0,Attack.cell_count()-1 do
			local cell = Attack.cell_get(k)
			local dist = 1
			if Attack.cell_dist(target,cell) <=dist
			and not Attack.act_equal(cell, 0) then
				table.insert(subtargets, cell)
			end
		end
		local n = 10
		local subtarget = 0
		local a = Attack.atom_spawn(target, dmgt, "effect_earthqrake")
		local dmgt1 = Attack.aseq_time(a, "x")
		local pdmg_min,pdmg_max = text_range_dec(Attack.get_custom_param("damage1"))
		local fdmg_min,fdmg_max = text_range_dec(Attack.get_custom_param("damage2"))
		local duration = Attack.get_custom_param("duration")
		local k = tonumber(Attack.get_custom_param("k"))
		for i = 1,n do
			local r = Game.CurLocRand(1,table.getn(subtargets))
			subtarget = subtargets[r]
			local frame = dmgt+dmgt1+(i*.3)
			local b = Attack.atom_spawn(subtarget, frame, "magic_fireground_"..math.random(1,3), Game.Dir2Ang(math.random(0,5)))
			local frame1 = Attack.aseq_time(b, "x")
			if n-i+1 <= table.getn(subtargets) and Attack.act_takesdmg(subtarget) then
				if not (Attack.act_feature(subtarget,"plant,golem,mech,undead,pawn,boss")
				or Attack.act_name(subtarget)=="griffin_spirit")
				and Game.CurLocRand(1,100) < k then
					if (Game.CurLocRand(1,100) <33 and Attack.act_level(subtarget)==5)
					or (Game.CurLocRand(1,100) <50 and Attack.act_level(subtarget)==4)
					or (Game.CurLocRand(1,100) <66 and Attack.act_level(subtarget)==3)
					or (Game.CurLocRand(1,100) <80 and Attack.act_level(subtarget) < 3) then
						effect_stun_attack(subtarget,frame+frame1+.3,duration,false)
					end
				end
				Attack.atk_set_damage("physical",math.floor((pdmg_min*(101-Attack.act_get_res(subtarget,"physical"))*.01)+(fdmg_min*(101-Attack.act_get_res(subtarget,"fire"))*.01)*100/(101-Attack.act_get_res(subtarget,"physical"))),math.floor((pdmg_max*(101-Attack.act_get_res(subtarget,"physical"))*.01)+(fdmg_max*(101-Attack.act_get_res(subtarget,"fire"))*.01)*100/(101-Attack.act_get_res(subtarget,"physical"))))
				common_cell_apply_damage(subtarget, frame+frame1)
				if table.getn(subtargets) > 1 then
					table.remove(subtargets, r)
				end
			elseif Attack.act_takesdmg(subtarget) then
				Attack.act_animate(subtarget, "damage", frame+frame1)
			end
		end
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end
--------
-- ***********************************************
-- * Compression Laser
-- ***********************************************
--------
function special_compression_laser()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "laser")
	local dmgts = Attack.aseq_time(0, "x")
	local a = Attack.atom_spawn(0,dmgts,"effect_compression_laser",Attack.angleto(0,target))
	local dmgts1 = Attack.aseq_time(a, "x")
	local pdmg_min,pdmg_max = text_range_dec(Attack.get_custom_param("damage1"))
	local admg_min,admg_max = text_range_dec(Attack.get_custom_param("damage2"))
	local dmg_min,dmg_max
	local targets = {}
	compression_laser_enum_targets(target, function (c) table.insert(targets, c) end)
	for i,target in ipairs(targets) do
		dmg_min = math.floor((pdmg_min*(101-Attack.act_get_res(target,"physical"))*.01)+(admg_min*(101-Attack.act_get_res(target,"astral"))*.01)*100/(101-Attack.act_get_res(target,"physical")))
		dmg_max = math.floor((pdmg_max*(101-Attack.act_get_res(target,"physical"))*.01)+(admg_max*(101-Attack.act_get_res(target,"astral"))*.01)*100/(101-Attack.act_get_res(target,"physical")))
		Attack.atk_set_damage("physical",dmg_min,dmg_max)
		common_cell_apply_damage(target, dmgts+dmgts1)
		Attack.atom_spawn(target, dmgts+dmgts1, "hll_lightning_after", 0, false)
	end
	return true
  
end

function compression_laser_enum_targets(target,func)

	local ang = Attack.angleto(0, target)
	local k = 0.8
	function select(c)
		if Attack.act_takesdmg(c) then
			if actor_name(c)~="drone" and actor_name(c)~="gizmo" and actor_name(c)~="alienegg" and actor_name(c)~="lightning_ball" and Attack.act_hp(c)>0 then
				func(c)
			end
		end
	end
	for i=1,Attack.act_count()-1 do
		local ang2 = Attack.angleto(0,i)
		local d = Attack.cell_mdist(0,i)
		local gamma = math.abs(ang - ang2)
		if gamma < 1 then
			if d*math.sin(gamma) < k then
				if not Attack.act_equal(0,i) then
					select(i)
				end
			end
		end
	end
	return true
end

function compression_laser_filter(cell,present)
  
	local pdmg_min,pdmg_max = text_range_dec(Attack.get_custom_param("damage1"))
	local admg_min,admg_max = text_range_dec(Attack.get_custom_param("damage2"))
	local dmg_min = math.floor((pdmg_min*(101-Attack.act_get_res(cell,"physical"))*.01)+(admg_min*(101-Attack.act_get_res(cell,"astral"))*.01)*100/(101-Attack.act_get_res(cell,"physical")))
	local dmg_max = math.floor((pdmg_max*(101-Attack.act_get_res(cell,"physical"))*.01)+(admg_max*(101-Attack.act_get_res(cell,"astral"))*.01)*100/(101-Attack.act_get_res(cell,"physical")))
	Attack.atk_set_damage("physical",dmg_min,dmg_max)
	if present then
		return true
	end
	return Attack.act_enemy(cell) and Attack.act_applicable(cell)
end

function compression_laser_highlight(target)
  
	compression_laser_enum_targets(target, function (c) Attack.cell_select(c, "avenemy") end)
	return true
end

function compression_laser_selcells()

	if Attack.is_computer_move() then
		local t1,t2,t3,t4,t5,t6,t7,t8,t9,t10 = {},{},{},{},{},{},{},{},{},{}
		local d1,d2,d3,d4 = {},{},{},{}
		local enemies = {}
		for i=1,Attack.act_count()-1 do
			if Attack.act_enemy(i)
			and Attack.act_takesdmg(i) then
				table.insert(enemies, i)
			end
		end
		for k,enemy in ipairs(enemies) do
			local count,anticount = 0,0
			local ang = Attack.angleto(0, enemy)
			local k = 0.8
			for i=1,Attack.act_count()-1 do
				local ang2 = Attack.angleto(0,i)
				local d = Attack.cell_mdist(0,i)
				local gamma = math.abs(ang - ang2)
				if gamma < 1 then
					if d*math.sin(gamma) < k
					and not Attack.act_equal(0,i)
					and Attack.act_takesdmg(i) then
						if Attack.act_ally(i) then
 							anticount = anticount + 1
						elseif Attack.act_enemy(i) then
							count = count + 1
						end
					end
				end
			end
			if anticount == 0 then
				if count >= 5 then
					table.insert(t1, enemy)
				elseif count >= 4 then
					table.insert(t2, enemy)
				elseif count >= 3 then
					table.insert(t3, enemy)
				elseif count >= 2 then
					table.insert(t4, enemy)
				elseif count >= 1 then
					table.insert(t5, enemy)
				end
			end
			if anticount <=1 then
				if count >= 5 then
					table.insert(t6, enemy)
				elseif count >= 4 then
					table.insert(t7, enemy)
				elseif count >= 3 then
					table.insert(t8, enemy)
				elseif count >= 2 then
					table.insert(t9, enemy)
				elseif count >= 1 then
					table.insert(t10, enemy)
				end
			end
		end
		if table.getn(t1) > 0 then
			for k,v in ipairs(t1) do
				Attack.marktarget(v)
			end
		elseif table.getn(t2) > 0 then
			for k,v in ipairs(t2) do
				Attack.marktarget(v)
			end
		elseif table.getn(t3) > 0 then
			for k,v in ipairs(t3) do
				Attack.marktarget(v)
			end
		elseif table.getn(t4) > 0 then
			for k,v in ipairs(t4) do
				Attack.marktarget(v)
			end
		elseif table.getn(t5) > 0 then
			for i=1,Attack.act_count()-1 do
				for k,v in ipairs(t5) do
					if Attack.act_equal(v, i) then
						if Attack.act_get_res(i,"physical") < 0 then
							table.insert(d1, i)
						elseif Attack.act_get_res(i,"physical") == 0 then
							table.insert(d2, i)
						elseif Attack.act_get_res(i,"physical") <= Attack.act_get_res(i,"magic")
						and Attack.act_get_res(i,"physical") <= Attack.act_get_res(i,"fire")
						and Attack.act_get_res(i,"physical") <= Attack.act_get_res(i,"poison") then
							table.insert(d3, i)
						else
							table.insert(d4, i)
						end
					end
				end
			end
			if table.getn(d1) > 0 then
				local tgt = ai_hp_count(d1)
				Attack.marktarget(tgt)
			elseif table.getn(d2) > 0 then
				local tgt = ai_hp_count(d2)
				Attack.marktarget(tgt)
			elseif table.getn(d3) > 0 then
				local tgt = ai_hp_count(d3)
				Attack.marktarget(tgt)
			elseif table.getn(d4) > 0 then
				local tgt = ai_hp_count(d4)
				Attack.marktarget(tgt)
			end
		elseif table.getn(t6) > 0 then
			for k,v in ipairs(t6) do
				Attack.marktarget(v)
			end
		elseif table.getn(t7) > 0 then
			for k,v in ipairs(t7) do
				Attack.marktarget(v)
			end
		elseif table.getn(t8) > 0 then
			for k,v in ipairs(t8) do
				Attack.marktarget(v)
			end
		elseif table.getn(t9) > 0 then
			for k,v in ipairs(t9) do
				Attack.marktarget(v)
			end
		elseif table.getn(t10) > 0 then
			for i=1,Attack.act_count()-1 do
				for k,v in ipairs(t10) do
					if Attack.act_equal(v, i) then
						if Attack.act_get_res(i,"physical") < 0 then
							table.insert(d1, i)
						elseif Attack.act_get_res(i,"physical") == 0 then
							table.insert(d2, i)
						elseif Attack.act_get_res(i,"physical") <= Attack.act_get_res(i,"magic")
						and Attack.act_get_res(i,"physical") <= Attack.act_get_res(i,"fire")
						and Attack.act_get_res(i,"physical") <= Attack.act_get_res(i,"poison") then
							table.insert(d3, i)
						else
							table.insert(d4, i)
						end
					end
				end
			end
			if table.getn(d1) > 0 then
				local tgt = ai_hp_count(d1)
				Attack.marktarget(tgt)
			elseif table.getn(d2) > 0 then
				local tgt = ai_hp_count(d2)
				Attack.marktarget(tgt)
			elseif table.getn(d3) > 0 then
				local tgt = ai_hp_count(d3)
				Attack.marktarget(tgt)
			elseif table.getn(d4) > 0 then
				local tgt = ai_hp_count(d4)
				Attack.marktarget(tgt)
			end
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if Attack.cell_dist(0,i) > 1
			and (Attack.act_enemy(i) or Attack.act_pawn(i))
			and not Attack.act_ally(i)
			and Attack.act_takesdmg(i)
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end

function ai_hp_count_laser(target)

	local tgt = nil
	local tgtcount,hpoutput = nil,nil
	for k,v in ipairs(target) do
		local hpinput = Attack.act_totalhp(v)
		if hpoutput == nil or hpinput < hpoutput then
			hpoutput = hpinput;
			tgtcount = v
		end
	end
	if tgtcount ~= nil then
		tgt = tgtcount
	end
	return tgt
end
--------
-- ***********************************************
-- * Explosive Device
-- ***********************************************
--------
function special_explosive_device()

	Attack.act_aseq(0, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local a = Attack.atom_spawn(0, dmgt, "effect_explosion")
	local dmgt1 = Attack.aseq_time(a, "x")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	--[[local fdmg_min,fdmg_max = text_range_dec(Attack.get_custom_param("damage1"))
	local admg_min,admg_max = text_range_dec(Attack.get_custom_param("damage2"))]]
	local power = tonumber(Attack.act_size(0))
	local pain = tonumber((Attack.act_initsize(0) - power)*3/power)

	for dir=0,5 do
		local d = Attack.cell_adjacent(0, dir)
		if Attack.act_takesdmg(d) then
			local paralysis = Attack.get_custom_param("paralysis")
			local duration = Attack.get_custom_param("duration")
			Attack.atk_set_damage("astral",dmg_min*pain,dmg_max*pain)
			--Attack.atk_set_damage("fire",math.floor((fdmg_min*(101-Attack.act_get_res(d,"fire"))*.01)+(admg_min*(101-Attack.act_get_res(d,"astral"))*.01)*100/(101-Attack.act_get_res(d,"fire")))*pain,math.floor((fdmg_max*(101-Attack.act_get_res(d,"fire"))*.01)+(admg_max*(101-Attack.act_get_res(d,"astral"))*.01)*100/(101-Attack.act_get_res(d,"fire")))*pain)
			if not (Attack.act_feature(d,"golem,mech,undead,pawn,boss") or Attack.act_name(d)=="griffin_spirit")
			and ((Game.CurLocRand(1,100) <50 and Attack.act_level(d)==5)
			or (Game.CurLocRand(1,100) <60 and Attack.act_level(d)==4)
			or (Game.CurLocRand(1,100) <80 and Attack.act_level(d)==3)
			or (Game.CurLocRand(1,100) <100 and Attack.act_level(d) < 3)) then
				effect_paralysis_attack(d,dmgt+dmgt1+.3,paralysis,false)
				if Attack.act_size(d)>1 then
					Attack.log(0.001,"add_blog_gamma_ray_paralysis", "target",""..blog_side_unit(d,1))
				end
			end
			effect_explosive_radiation(d,dmgt+.3,duration,false)
			common_cell_apply_damage(d, dmgt+dmgt1)
		end
	end
	Attack.act_kill(0,false,false)
	return true
end

function effect_explosive_radiation(target,pause,duration,dod)

	if pause==nil then
		pause = 1
	end
	if duration==nil then
		duration = tonumber(Logic.obj_par("effect_radiation","duration"))
	end
	if dod==nil then
		dod = true
	end
	if target~=nil then
		if (Attack.act_ally(target)
		or Attack.act_enemy(target))
		and not Attack.act_feature(target,"boss,pawn") then
			Attack.act_del_spell(target, "effect_radiation")
			Attack.act_apply_spell_begin(target, "effect_radiation", duration, dod)
			Attack.act_apply_res_spell("astral", -50, 0, 0, duration, dod)
			Attack.act_apply_spell_end()
			if Attack.act_size(target)>1 then
				Attack.log(0.001,"add_blog_radiation", "name",""..blog_side_unit(target,1))
			end
		end
	end
	return true
end

function calccells_explosive_device()

	if Attack.is_computer_move() then

		if Attack.act_size(0) < Attack.act_initsize(0)*.3 then
			local enemies = {}
			local count = 0
			for dir=0,5 do
				local d = Attack.cell_adjacent(0, dir)
				if Attack.act_ally(d) then
					count = -5
				elseif Attack.act_enemy(d) then
					count = count + 1
				end
			end
			if count >= 6 then
				Attack.multiselect(0)
			elseif count >= 5 then
				Attack.multiselect(0)
			elseif count >= 4 then
				Attack.multiselect(0)
			elseif count >= 3 then
				Attack.multiselect(0)
			elseif count >= 2 then
				Attack.multiselect(0)
			end
		end
	else
		for dir=0,5 do
			local d = Attack.cell_adjacent(0, dir)
			if Attack.act_enemy(d)
			and Attack.act_applicable(d) then
				Attack.multiselect(0)
				break
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Astrasz Eat
-- ***********************************************
--------
function special_astrasz_eat()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "special")
	local dmgt = Attack.aseq_time(0, "x")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local typedmg=Attack.get_custom_param("typedmg")
	local k = Attack.get_custom_param("k")
	local dmg,hp,result = 0,0,0
	Attack.atk_set_damage(typedmg,dmg_min,dmg_max)
	common_cell_apply_damage(target,dmgt)
	if not (Attack.act_feature(target,"plant,golem,mech,pawn,boss")
	or Attack.act_name(target)=="skeleton"
	or Attack.act_name(target)=="archer"
	or Attack.act_name(target)=="ghost"
	or Attack.act_name(target)=="ghost2"
	or Attack.act_name(target)=="blackknight"
	or Attack.act_name(target)=="bonedragon"
	or Attack.act_name(target)=="griffin_spirit") then
		hp = Attack.act_totalhp(target)
		result = Attack.act_damage_results(target)
		if result ==nil then result = 0 end
		dmg = math.min(hp, result)
	end
	if dmg > 0 then
  		local a = Attack.atom_spawn(0, dmgt, "effect_total_cure")
  		local dmgt1 = Attack.aseq_time(a, "x")
		drain = math.floor(dmg*k/100)
		local count = tonumber(Attack.act_size(0))
		Attack.cell_resurrect(0, dmg, dmgt+dmgt1)
		Attack.act_cure(0, -dmg, dmgt+dmgt1)
		count = Attack.act_size(0) - count

		if count == 0 then
			Attack.log(0.001,"add_blog_lifedrain3_cure","name",""..blog_side_unit(0,1), "special",""..dmg)
		else
			Attack.log(0.001,"add_blog_lifedrain3_resr","name",""..blog_side_unit(0,1), "special",""..dmg, "special2",""..count)
		end
	end	
	return true
end

function calccells_astrasz_eat()

	if Attack.is_computer_move() then
		local power = Attack.act_size(0)
		local hp = Attack.act_get_par(0,"health")
		local loss1 = Attack.act_initsize(0) - power
		local loss2 = hp - Attack.act_hp(0)
		local need = (loss1*hp) + loss2
		local heal = tonumber(Attack.get_custom_param("heal"))*power
		if need > heal then
			for dir=0,5 do
				local d = Attack.cell_adjacent(0, dir)
				if Attack.act_enemy(d)
				and Attack.act_size(d)>1
				and not (Attack.act_feature(d,"plant,golem,mech,pawn,boss")
				or Attack.act_name(d)=="skeleton"
				or Attack.act_name(d)=="archer"
				or Attack.act_name(d)=="ghost"
				or Attack.act_name(d)=="ghost2"
				or Attack.act_name(d)=="blackknight"
				or Attack.act_name(d)=="bonedragon"
				or Attack.act_name(d)=="griffin_spirit")
				and Attack.act_applicable(d) then
					Attack.marktarget(d)
				end
			end
		end
	else
		for dir=0,5 do
			local d = Attack.cell_adjacent(0, dir)
			if (Attack.act_ally(d) or Attack.act_enemy(d))
			and Attack.act_applicable(d) then
				Attack.marktarget(d)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Local Earthquake
-- ***********************************************
--------
function special_local_earthquake()

	Attack.act_aseq(0,"special2")
	local dmgt = Attack.aseq_time(0, "x")
	local skill = Attack.val_restore(0,"skill")
	local skill_used = tonumber(Attack.get_custom_param("skill_used"))
	if skill==nil then skill = 0 end
	local subtargets = {}
	for k=0,Attack.cell_count()-1 do
		local cell = Attack.cell_get(k)
		local dist = 2
		if Attack.cell_dist(0,cell) <=dist
		and not Attack.act_equal(cell, 0) then
			table.insert(subtargets, cell)
		end
	end
	local n = 10
	local subtarget = 0
	local a = Attack.atom_spawn(0, dmgt, "effect_local_qrake")
	local dmgt1 = Attack.aseq_time(a, "x")
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local duration = Attack.get_custom_param("duration")
	local k = tonumber(Attack.get_custom_param("k"))
	for i = 1,n do
		local r = Game.CurLocRand(1,table.getn(subtargets))
		subtarget = subtargets[r]
		local frame = dmgt+dmgt1+(i*.3)
		local b = Attack.atom_spawn(subtarget, frame-1, "effect_local_qrake_smoke")
		local frame1 = Attack.aseq_time(b, "x")
		if table.getn(subtargets) > 1 then
			table.remove(subtargets, r)
		end
	end
	for k=0,Attack.cell_count()-1 do
		local cell = Attack.cell_get(k)
		if Attack.act_takesdmg(cell)
		and Attack.act_mt(cell)==0 then
			local ramdom = Game.CurLocRand(150,350)
			if Attack.cell_dist(0,cell) <=2
			and not Attack.act_equal(cell, 0) then
				if not (Attack.act_feature(cell,"plant,golem,mech,undead,pawn,boss")
				or Attack.act_name(cell)=="griffin_spirit")
				and Game.CurLocRand(1,100) < k then

					if (Game.CurLocRand(1,100) <10 and Attack.act_level(cell)==5)
					or (Game.CurLocRand(1,100) <20 and Attack.act_level(cell)==4)
					or (Game.CurLocRand(1,100) <40 and Attack.act_level(cell)==3)
					or (Game.CurLocRand(1,100) <60 and Attack.act_level(cell) < 3) then
						effect_stun_attack(cell,dmgt+(ramdom*.01)+.3,duration,false)
					end
				end
				if Attack.cell_dist(0,cell) ==1 then
					Attack.atk_set_damage("physical",dmg_min,dmg_max)
				elseif Attack.cell_dist(0,cell) ==2 then
					Attack.atk_set_damage("physical",dmg_min*.5,dmg_max*.5)
				end
				common_cell_apply_damage(cell, dmgt+(ramdom*.01))
				Attack.atom_spawn(cell, dmgt+(ramdom*.01), "effect_local_qrake_dmg")
			end
		elseif Attack.act_takesdmg(cell)
		and Attack.act_mt(cell)==2
		and Attack.cell_dist(0,cell) <=2
		and not Attack.act_equal(cell, 0) then
			local ramdom = Game.CurLocRand(150,350)
			Attack.act_animate(cell, "takeoff", dmgt+(ramdom*.01))
			Attack.act_animate(cell, "descent", dmgt+(ramdom*.01))
		end
	end
	skill = skill - skill_used
	if skill < 0 then skill = 0 end
	Attack.val_store(0,"skill",skill)
	return true
end

function calccells_local_earthquake()

	if Attack.is_computer_move() then

		local count = 0
		for i=0,Attack.cell_count()-1 do
			local d = Attack.cell_get(i)
			if Attack.cell_dist(0,d) <=2
			and not Attack.act_equal(d, 0)
			and Attack.act_mt(d)==0
			and Attack.act_applicable(d) then
				if Attack.act_ally(d)
				and Attack.act_name(d)=="astrasz" then
					count = count - 0.5
				elseif Attack.act_ally(d) then
					count = count - 1
				elseif Attack.act_enemy(d) then
					count = count + 1
				end
			end
		end
		if count >= 6 then
			Attack.multiselect(0)
		elseif count >= 5 then
			Attack.multiselect(0)
		elseif count >= 4 then
			Attack.multiselect(0)
		elseif count >= 3 then
			Attack.multiselect(0)
		elseif count >= 2 then
			Attack.multiselect(0)
		end
	else
		for i=0,Attack.cell_count()-1 do
			local d = Attack.cell_get(i)
			if Attack.cell_dist(0,d) <=2
			and not Attack.act_equal(d, 0)
			and Attack.act_enemy(d)
			and Attack.act_applicable(d) then
				Attack.multiselect(0)
				break
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Summon Units
-- ***********************************************
--------
function special_summon_units()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local a = Attack.atom_spawn(target,dmgt,"effect_deadarise")
	local dmgt1 = Attack.aseq_time(a, "x")
	local k=Game.CurLocRand(text_range_dec(Attack.get_custom_param("k")))
	local units=Attack.get_custom_param("units")
	local summon_unit=text_dec(units,Game.CurLocRand(1,text_par_count(units)))
	local unit_count=Attack.act_size(0)
	local unit_name=Attack.act_name(0)
	local unit_lead=Attack.atom_getpar(unit_name,"leadership")
	local summon_lead=Attack.atom_getpar(summon_unit,"leadership")
	local summon_count=math.ceil(unit_lead*unit_count/summon_lead*k/100*(1+tonumber(skill_power2("summonner",1)/100)))
	if summon_count < 1 then summon_count = 1 end
	local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0

	for i=1,Attack.act_count()-1 do

		if Attack.act_enemy(i) then
			local d = Attack.cell_dist(target,i)

			if d < nearest_dist then
				nearest_dist = d;
				nearest_enemy = i;
			end
		end
	end

	if nearest_enemy ~= nil then
		ang_to_enemy = Attack.angleto(target, nearest_enemy)
	end

	Attack.act_spawn(target, 0, summon_unit, ang_to_enemy, summon_count)
	Attack.act_nodraw(target, true)
	Attack.act_animate(target, "slew", dmgt+dmgt1)
	Attack.act_nodraw(target, false, dmgt+dmgt1)
	Attack.log_label("add_blog_summon_")
	Attack.log_special(summon_count)
	return true
end
--------
-- ***********************************************
-- * Summon Magic Tower
-- ***********************************************
--------
function special_summon_tower()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local power = tonumber(Attack.act_size(0))
	local health = tonumber(Attack.get_custom_param("health"))*tonumber(Attack.act_size(0))
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end

	if target~=nil then

		local farest_dist, farest_enemy, ang_to_enemy = 0e0, nil, 0

		for k=1,Attack.act_count()-1 do

			if Attack.act_enemy(k) then
				local d = Attack.cell_dist(0,k)

				if d > farest_dist then farest_dist = d; farest_enemy = k; end
			end
		end

		if farest_enemy ~= nil then ang_to_enemy = Attack.angleto(target, farest_enemy) end
		local tower = Attack.atom_spawn(target, 0, "magic_tower", ang_to_enemy)
		Attack.act_nodraw(tower, true)
		Attack.act_animate(tower, "appear", dmgt)
		Attack.act_nodraw(tower, false, dmgt)
		local edg = 1
		if Attack.act_belligerent(0) == 1 then edg = 0 end
		Attack.act_edge(tower , edg)
		Attack.val_store(tower, "belligerent", Attack.act_belligerent(0))
		Attack.act_hp(tower, health)
		Attack.act_set_par(tower, "health",health)
		Attack.act_set_par(tower, "attack", math.floor(power*.1+10))
		Attack.act_set_par(tower, "defense", math.floor(power*.2+5))
		Attack.val_store(tower, "intellect", power*.5+5)
		Attack.val_store(tower, "power", power)
		Attack.resort(tower)
		Attack.log(0.001,"add_blog_summon_magic_tower","targets",""..blog_side_unit(tower,0),"name",""..blog_side_unit(0,1))
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end
--------
-- ***********************************************
-- * Auto Cast Spells
-- ***********************************************
--------
function special_auto_cast_spells()

	local spells = {}
	local str_spells = Attack.atom_getpar(Attack.act_name(0), "spells")
	for k, v in string.gfind(str_spells, "([%w_]+)=(%w+)") do
		spells[k] = tonumber(v)
	end

	local start = 1.
	local r = spell_auto_cast(spells)
	if r ~= nil then
		Attack.atom_spawn(0, 0, "effect_unit_turn", 0)
		Attack.cast_spell(r.spell, spells[r.spell], 4, r.target, r.target2, start+Attack.aseq_time(0,"cast","x")-0.5)
		Attack.act_animate(0,"cast",start)
	end
	return true
end
--------
-- ***********************************************
-- * Weak Point Attack
-- ***********************************************
--------
function special_weak_point_attack()

	Attack.log_label('null')
	local targets = {}

	for i=1, Attack.act_count()-1 do
		if not Attack.act_ally(i) and Attack.act_takesdmg(i) then
			table.insert(targets, i)
		end
	end

	if table.getn(targets) > 0 then

		local target = targets[Game.CurLocRand(1,table.getn(targets))]
		Attack.act_aseq(0,"cast")
		local dmgts = Attack.aseq_time(0,"x")
		local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
		local duration = tonumber(Attack.get_custom_param("duration"))
		local k = tonumber(Attack.get_custom_param("k"))
		local power = Attack.val_restore(0,"power")

		if Game.CurLocRand(1,100) < k
		and not Attack.act_is_spell(target, "spell_ram")
		and not Attack.act_feature(target,"golem,mech,pawn,boss,magic_immunitet") then

			ks_dispell(target)
			Attack.act_apply_spell_begin(target, "spell_ram", duration, false)
			Attack.act_apply_par_spell("autofight", 1, 0, 0, duration, false)
			Attack.act_apply_par_spell("hitback", 0, 0, -100, duration, false, 1000)
			Attack.act_apply_spell_end()
			Attack.val_store(target,"initial_tag",actor_name(target))
			local l = 1
			Attack.act_fadeout(target, 0, l)
			Attack.act_change_tag(target,"ram",l)
			Attack.atom_spawn(target, 0, "magic_ram")
			Attack.atom_spawn(target, l - Attack.aseq_time("magic_ram", "x"), "magic_ram", Attack.angleto(target))
			Attack.act_fadeout(target, l, l*2, 1)

			if Attack.act_size(target)>1 then
				Attack.log(0.001,"add_blog_ram_for_magic_tower","targets", ""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1))
			end
		else
			local physical = Attack.act_get_res(target,"physical")
			local magic = Attack.act_get_res(target,"magic")
			local fire = Attack.act_get_res(target,"fire")
			local poison = Attack.act_get_res(target,"poison")
			local typedmg
			local frame

			if magic <= physical and magic <= fire and magic <= poison then

				typedmg = "magic"
				local a = Attack.atom_spawn(target, dmgts, "magic_lightning")
				local dmgts1 = Attack.aseq_time(a, "x")
				frame = dmgts+dmgts1

				if Game.CurLocRand(1,100) < k then
					effect_shock_attack(target,frame+1,duration)
				end

			elseif physical <= magic and physical <= fire and physical <= poison then

				typedmg = "physical"
				local a = Attack.atom_spawn(target,dmgts,"magic_armageddon_spawn")
				local spawn_shift = Attack.aseq_time(a, "x")+dmgts
				local start_up = Attack.aseq_time("magic_armageddon","w")
				local end_up   = Attack.aseq_time("magic_armageddon","x")
				local start_down = Attack.aseq_time("magic_armageddon","y")
				local end_down   = Attack.aseq_time("magic_armageddon","z")
				local t = dmgts+Game.CurLocRand(100)/100.-1.
				Attack.atom_spawn(target,t,"magic_armageddon")
				local hit_time = t + end_down
				local tx,ty,tz = Attack.act_get_center(target)
				Attack.act_move( t+start_up, t+end_up, target, tx, ty, tz+3)
				Attack.act_rotate( t+end_up, t+start_down, target, Game.Dir2Ang(Attack.act_dir(target))+2*math.pi*(2*math.random(0,1)-1) )
				local t1 = t + lerp(end_up, start_down, 1/6.)
				local t2 = t + lerp(end_up, start_down, 3/6.)
				local t3 = t + lerp(end_up, start_down, 5/6.)
				Attack.act_move( t+end_up, t1, target, tx, ty, tz+2.7)
				Attack.act_move( t1, t2, target, tx, ty, tz+3.3)
				Attack.act_move( t2, t3, target, tx, ty, tz+2.7)
				Attack.act_move( t3, t+start_down, target, tx, ty, tz+3)
				Attack.act_falldown( t+start_down, hit_time, target, tz)
				frame = hit_time

				if Game.CurLocRand(1,100) < k and not Attack.act_feature(target,"freeze_immunitet") then
					effect_freeze_attack(target,frame+1,duration)
				end

			elseif fire <= physical and fire <= magic and fire <= poison then

				typedmg = "fire"
				local a = Attack.atom_spawn(target, dmgts-.5, "effect_fire_cyclone")
				local dmgts1 = Attack.aseq_time(a, "x")
				local b = Attack.atom_spawn(target, dmgts+.6, "effect_fire_torch")
				local dmgts2 = Attack.aseq_time(b, "x")
				frame = dmgts+dmgts1+dmgts2

				if Game.CurLocRand(1,100) < k and not Attack.act_feature(target,"fire_immunitet") then
					effect_burn_attack(target,frame+.3,duration)
				end

			elseif poison <= physical and poison <= magic and poison <= fire then

				typedmg = "poison"
				local a = Attack.atom_spawn(target, dmgts, "magic_skull", Attack.angleto(target))
				local dmgts1 = Attack.aseq_time(a, "x")
				frame = dmgts+dmgts1

				if Game.CurLocRand(1,100) < k then
					effect_poison_attack(target,frame+1,duration)
				end

			end

			Attack.atk_set_damage(typedmg,dmg_min*power,dmg_max*power)
			common_cell_apply_damage(target, frame)
			Attack.log_label("")
		end
	end
	return true
end
--------
-- ***********************************************
-- * Totem Sorcery
-- ***********************************************
--------
function special_totem_sorcery()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local health = tonumber(Attack.get_custom_param("health"))*tonumber(Attack.act_size(0))
	local power = tonumber(Attack.act_size(0))
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end

	if target~=nil then

		local totem = Attack.atom_spawn(target, 0, "totem_sorcery")
		Attack.act_nodraw(totem, true)
		Attack.act_animate(totem, "appear", dmgt)
		Attack.act_nodraw(totem, false, dmgt)
		local edg = 1
		if Attack.act_belligerent(0) == 1 then edg = 0 end
		Attack.act_edge(totem , edg)
		Attack.val_store(totem, "belligerent", Attack.act_belligerent(0))
		Attack.act_hp(totem, health)
		Attack.act_set_par(totem, "health",health)
		Attack.act_set_par(totem, "attack", math.floor(power*.15+5))
		Attack.act_set_par(totem, "defense", math.floor(power*.1+5))
		Attack.val_store(totem, "power", power)
		Attack.resort(totem)
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end


function calccells_totem_sorcery()

	local owner,caltotems,failcells = {},{},{}
	local effect = {}

	for k=1, Attack.act_count()-1 do
		if Attack.act_ally(k) and Attack.act_name(k) == "totem_sorcery" then
			table.insert(caltotems, k)
		end
		if (Attack.act_name(k)=="totem_sorcery" or Attack.act_name(k)=="totem_death" or Attack.act_name(k)=="totem_life") then
			table.insert(owner, k)
		end
		if Attack.act_feature(k,"pawn,boss")
		or Attack.act_ally(k)
		or Attack.act_enemy(k) then
			table.insert(failcells, k)
		end
	end
	for c=0,Attack.cell_count()-1 do
		local count = 0
		local i = Attack.cell_get(c)
		for k,v in ipairs(owner) do
			if Attack.cell_dist(v,i) <=1 then
				count = count + 1
			end
		end
		for l,w in ipairs(failcells) do
			if Attack.cell_dist(w,i) <=1 then
				count = count + 1
			end
		end
		if count == 0
		and Attack.cell_is_empty(i)
		and Attack.cell_is_pass(i)
		and Attack.cell_dist(0,i) <=3 then
			table.insert(effect, i)
		end
	end
	if table.getn(caltotems) < 3
	and table.getn(effect) > 0 then
		for k,v in ipairs(effect) do
			Attack.marktarget(v)
		end
	end
	return true
end
--------
-- ***********************************************
-- * Totem Summon Ghost
-- ***********************************************
--------
function totem_summon_ghost()

	Attack.log_label('null')
	local targets = {}
	for k=0,Attack.cell_count()-1 do
		local cell = Attack.cell_get(k)
		local  dist = tonumber(Attack.val_restore("dist"))
		if dist == nil then dist = 1 end
		if Attack.cell_present(cell)
		and Attack.cell_is_empty(cell)
		and Attack.cell_is_pass(cell) 
		and Attack.cell_dist(0,cell) <=dist then
			table.insert(targets, cell)
		end
	end

	local n = tonumber(Attack.get_custom_param("number"))
	if table.getn(targets) < n then
		n = table.getn(targets)
	end
	if table.getn(targets) >= n and table.getn(targets) > 0 then

		Attack.act_aseq(0,"attack")
		local dmgt = Attack.aseq_time(0,"x")

		local target = 0
		for i=1,n do

			local r = Game.CurLocRand(1,table.getn(targets))
			target = targets[r]
			local frame = dmgt-.5+(i*.5)
			local a = Attack.atom_spawn(target,frame,"effect_deadarise")
			local frame1 = Attack.aseq_time(a, "x")
			local belligerent = tonumber(Attack.val_restore(0,"belligerent"))
			if belligerent == 1 then belligerent = 2 end
			local k = Game.CurLocRand(text_range_dec(Attack.get_custom_param("k")))
			local units = Attack.get_custom_param("units")
			local summon_unit = text_dec(units,Game.CurLocRand(1,text_par_count(units)))
			local unit_count = Attack.val_restore(0,"power")
			local summon_lead = tonumber(Attack.atom_getpar(summon_unit,"leadership"))
			local summon_count = math.floor(450*unit_count/summon_lead*k/100)
			if summon_count < 1 then summon_count = 1 end
			local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
			for i=1,Attack.act_count()-1 do

				if Attack.act_enemy(i) then
					local d = Attack.cell_dist(target,i)

					if d < nearest_dist then
						nearest_dist = d;
						nearest_enemy = i;
					end
				end
			end
			if nearest_enemy ~= nil then
				ang_to_enemy = Attack.angleto(target,nearest_enemy)
			end
			Attack.act_spawn(target, belligerent, summon_unit, ang_to_enemy, summon_count)
			Attack.act_apply_spell_begin(target, "ks_effect_temporary_ghost", 1, false)
			Attack.act_posthitslave(target,"post_totem_ghost_debuff",100)
			Attack.act_apply_spell_end()
			Attack.act_nodraw(target, true)
			Attack.act_fadeout(target, 0, frame+frame1, 1)
			Attack.act_animate(target, "spare", frame+frame1)
			Attack.act_nodraw(target, false, frame+frame1)
			Attack.resort(target)
			table.remove(targets, r)
			Attack.log(0.001,"add_blog_totem_summon_ghost", "target",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1),"special",""..summon_count)
		end
	end
	return true
end
--------
-- ***********************************************
-- * Summon Drones
-- ***********************************************
--------
function special_summon_drones()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local duration = Attack.get_custom_param("duration")
	local power = tonumber(Attack.act_size(0))
	if target~=nil then
		local drone = Attack.atom_spawn(target, dmgt, "drone", 0)
		Attack.act_nodraw(drone, true)
		Attack.act_animate(drone, "appear", dmgt)
		Attack.act_nodraw(drone, false, dmgt)
		Attack.val_store(drone, "belligerent", Attack.act_belligerent(0))
		Attack.act_set_par(drone, "attack", math.floor(power*.1+10))
		Attack.val_store(drone, "power", power)
		Attack.val_store(drone, "time_last", duration+1)
		Attack.resort(drone)
	end
	return true
end

function drone_idle()

	local duration = tonumber(Attack.val_restore("time_last"))
	if duration > 3 then duration = 3 end
	Atom.animate("idle3")
end

function drone_attack()

	Attack.log_label('null')
	local duration = Attack.val_restore("time_last")
	local bel = Attack.val_restore("belligerent")
	local power = Attack.val_restore("power")
	if power == nil then power = 1 end
	local under, target = Attack.get_caa(Attack.get_cell(0))
	local function ally_check(i)
		if Attack.act_pawn(i) then return false end
		return Attack.act_need_cure(i) and Attack.act_feature(i,"mech") and (tonumber(Attack.act_initsize(i)*Attack.act_get_par(i,"health")) - Attack.act_totalhp(i)) > 0
	end
	local can_stay_here = false
	if under ~= nil then
		if Attack.act_ally(under, bel) then
			can_stay_here = ally_check(under)
		elseif Attack.act_enemy(under, bel) then
			can_stay_here = true
		end
	end
	local drone_ids = {}
	for i=1, Attack.act_count()-1 do
		if Attack.act_name(i) == "drone" or Attack.act_name(i) == "gizmo" or Attack.act_name(i) == "lightning_ball" then
			drone_ids[Attack.cell_id(Attack.get_cell(i))] = true
		end
	end
	local ap, rand = 4, Game.Random(1,100)
	if can_stay_here and rand < 33 then
		target = under
	else
		local dist = 1e3
		for a=1, Attack.act_count()-1 do
			local i = Attack.get_cell(a)
			if (under == nil or not Attack.act_equal(under, i))
			and drone_ids[Attack.cell_id(Attack.get_cell(i))] ~= true then
				local d = Attack.cell_mdist(0, i)
				if d < dist and (Attack.act_enemy(i, bel) and not Attack.act_feature(i,"boss")) then
					dist = d;
					target = i
				elseif d < dist and (Attack.act_ally(i, bel) and ally_check(i)) then
					dist = d;
					target = i
				end
			end
		end
		if can_stay_here
		and (dist / 1.8 > ap*1.5 or (dist / 1.8 > ap + 1 and rand < 66)) then
			target = under
		end
	end
	if target ~= nil then
		local d = Attack.cell_mdist(0, target) / 1.8
		if d > ap + 1 then
			for i=ap,1,-1 do
				local dist = 1.8 * i
				local x, y = Attack.act_get_center(0)
				local dx, dy = Attack.act_get_center(target)
				dx = dx - x; dy = dy - y
				local len = math.sqrt(dx*dx + dy*dy)
				dx = dx*dist/len; dy = dy*dist/len
				local dest = Attack.find_nearest_cell(x + dx, y + dy)
				if drone_ids[Attack.cell_id(dest)] ~= true then
					Attack.act_move(0, i*.3, 0, dest)
					break
				end
			end
		else
			Attack.act_move(0, d*.3, 0, target)
			if Attack.act_ally(target, bel) then
				Attack.log_label('')
				Attack.act_aseq(0, "cast3")
				local heal = tonumber(Attack.get_custom_param("heal"))*power
				local n = tonumber(Attack.act_initsize(target)*Attack.act_get_par(target,"health"))
				if n < heal then heal = n end
				heal = math.floor(heal)
				local count = tonumber(Attack.act_size(target))
				Attack.cell_resurrect(target, heal, d*.3 +Attack.aseq_time(0, "x"))
				Attack.act_cure(target, -heal, d*.3 +Attack.aseq_time(0, "x"))
				count = tonumber(Attack.act_size(target)) - count
				if count == 0 then
					Attack.log(0.001,"add_blog_mech_repair_cure", "targets",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1), "special",""..heal)
				else
					Attack.log(0.001,"add_blog_mech_repair_resr", "targets",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1), "special",""..heal, "special2",""..count)
				end
				if duration == 1 then
					Attack.act_aseq(0, "disappear")
					Attack.act_remove(0, d*.3 +Attack.aseq_time(0))
					Attack.log("add_blog_temporary","name",blog_side_unit(0,1))
				else
					Attack.val_store(0, "time_last", duration-1, d+.1)
				end
			elseif Attack.act_enemy(target, bel) then
				Attack.log_label('')
				Attack.act_aseq(0, "attack3")
				local pdmg_min,pdmg_max = text_range_dec(Attack.get_custom_param("damage1"))
				local admg_min,admg_max = text_range_dec(Attack.get_custom_param("damage2"))
				dmg_min = math.floor((pdmg_min*(101-Attack.act_get_res(target,"physical"))*.01)+(admg_min*(101-Attack.act_get_res(target,"astral"))*.01)*100/(101-Attack.act_get_res(target,"physical")))*power
				dmg_max = math.floor((pdmg_max*(101-Attack.act_get_res(target,"physical"))*.01)+(admg_max*(101-Attack.act_get_res(target,"astral"))*.01)*100/(101-Attack.act_get_res(target,"physical")))*power
				Attack.atk_set_damage("physical",dmg_min,dmg_max)
				common_cell_apply_damage(target, d*.3 +Attack.aseq_time(0, "x"))
				if duration == 1 then
					Attack.act_aseq(0, "disappear")
					Attack.act_remove(0, d*.3 +Attack.aseq_time(0))
	  		  		Attack.log("add_blog_temporary","name",blog_side_unit(0,1))
				else
					Attack.val_store(0, "time_last", duration-1, d+.1)
				end
			end
			Attack.aseq_timeshift(0, d*.3)
		end
	end
	return true
end

function calccells_summon_drones()

	local caldrones,drone_ids = {},{}
	for i=1,Attack.act_count()-1 do
		if Attack.act_ally(i) and Attack.act_name(i) == "drone" then
			table.insert(caldrones, i)
		end
		if Attack.act_name(i) == "drone" or Attack.act_name(i) == "gizmo" or Attack.act_name(i) == "lightning_ball" then
			drone_ids[Attack.cell_id(Attack.get_cell(i))] = true
		end
	end
	if table.getn(caldrones) < 3 then
		for i=0,5 do
			local cell=Attack.cell_adjacent(0,i)
			if Attack.cell_present(cell) and Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell) and drone_ids[Attack.cell_id(Attack.get_cell(cell))] ~= true then
				Attack.marktarget(cell)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Gamma Ray
-- ***********************************************
--------
function special_gamma_ray()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "projector")
	local dmgts = Attack.aseq_time(0, "x")
	local duration = Attack.get_custom_param("duration")
	local targets = {}
	gamma_ray_enum_targets(target, function (c) table.insert(targets, c) end)
	for i,target in ipairs(targets) do
		local calcount = 0
		if not (Attack.act_feature(target,"golem,mech,undead,pawn,boss")
		or Attack.act_name(target)=="griffin_spirit") then
			calcount = 1
			Attack.atom_spawn(target, dmgts, "effect_dismissal")
			effect_paralysis_attack(target,dmgts,duration,false)
			Attack.log(0.001,"add_blog_gamma_ray_paralysis", "target",""..blog_side_unit(target,1))
		end
		local buff={}
		for i=0,Attack.act_spell_count(target)-1 do
			local spell_name=Attack.act_spell_name(target,i)
			local spell_type=Logic.obj_par(spell_name,"type")
			if spell_type=="bonus"
			and string.find(spell_name,"^totem_")==nil
			and string.find(spell_name,"^ks_effect_")==nil
			and spell_name ~= "spell_slime_glot"
			and spell_name ~= "spell_phantom" then
				table.insert(buff, spell_name)
			end
		end
		if table.getn(buff) > 0 then
			if calcount == 0 then
				Attack.atom_spawn(target, dmgts, "effect_dismissal")
			end
			Attack.act_del_spell(target, buff[Game.CurLocRand(1,table.getn(buff))])
			Attack.log(0.001,"add_blog_gamma_ray_remove_magic", "target",""..blog_side_unit(target,1))
			for k,v in pairs(buff) do
				table.remove(buff)
			end
		end
	end
	return true
end

function gamma_ray_selcells()

	if Attack.is_computer_move() then
		local targets1,targets2,targets3 = {},{},{}
		local enemies = {}
		local buff = {}
		for i=1,Attack.act_count()-1 do
			if Attack.act_enemy(i)
			and Attack.act_takesdmg(i) then
				table.insert(enemies, i)
			end
		end
		for k,enemy in ipairs(enemies) do
			local count = 0
			local ang = Attack.angleto(0, enemy)
			local k = 0.9
			for i=1,Attack.act_count()-1 do
				local ang2 = Attack.angleto(0,i)
				local d = Attack.cell_mdist(0,i)
				local gamma = math.abs(ang - ang2)
				if gamma < 1 then
					if d*math.sin(gamma) < k
					and not Attack.act_equal(0,i)
					and Attack.cell_dist(0,i) < 4 then
						if Attack.act_ally(i)
						and not (Attack.act_feature(i,"golem,mech,undead,pawn,boss") or Attack.act_name(i)=="griffin_spirit") then
 							count = -5
						elseif Attack.act_enemy(i)
						and not (Attack.act_feature(i,"golem,mech,undead,pawn,boss") or Attack.act_name(i)=="griffin_spirit")
						and not Attack.act_is_spell(i, "effect_paralysis") then
							count = count + 1
						else
							for n=0,Attack.act_spell_count(i)-1 do
								local spell_name=Attack.act_spell_name(i,n)
								local spell_type=Logic.obj_par(spell_name,"type")
								if spell_type=="bonus"
								and string.find(spell_name,"^totem_")==nil
								and string.find(spell_name,"^ks_effect_")==nil
								and spell_name ~= "spell_slime_glot"
								and spell_name ~= "spell_phantom" then
									table.insert(buff, spell_name)
									break
								end
							end
							if table.getn(buff) > 0 then
								if Attack.act_ally(i) then
									count = -5
								elseif Attack.act_enemy(i) then
									count = count + 1
								end
								for k,v in pairs(buff) do
									table.remove(buff)
								end
							end
						end
					end
				end
			end
			if count >= 3 then
				table.insert(targets1, enemy)
			elseif count >= 2 then
				table.insert(targets2, enemy)
			elseif count >= 1 then
				table.insert(targets3, enemy)
			end
		end
		if table.getn(targets1) > 0 then
			for k,v in ipairs(targets1) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets2) > 0 then
			for k,v in ipairs(targets2) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets3) > 0 then
			for k,v in ipairs(targets3) do
				Attack.marktarget(v)
			end
		end
	else
		for i=0,Attack.cell_count()-1 do
			local cell = Attack.cell_get(i)
			if Attack.cell_dist(0,cell) < 4 then
				if Attack.act_enemy(cell)
				and not (Attack.act_feature(cell,"golem,mech,undead,pawn,boss") or Attack.act_name(cell)=="griffin_spirit")
				and not Attack.act_is_spell(cell, "effect_paralysis")
				and Attack.act_applicable(cell) then
					Attack.marktarget(cell)
				else
					for k=0,Attack.act_spell_count(cell)-1 do
						local spell_name=Attack.act_spell_name(cell,k)
						local spell_type=Logic.obj_par(spell_name,"type")
						if Attack.act_enemy(cell)
						and spell_type=="bonus"
						and string.find(spell_name,"^totem_")==nil
						and string.find(spell_name,"^ks_effect_")==nil
						and spell_name ~= "spell_slime_glot"
						and spell_name ~= "spell_phantom"
						and Attack.act_applicable(cell) then
							Attack.marktarget(cell)
						end
					end
				end
			end
		end
	end
	return true
end

function gamma_ray_enum_targets(target,func)

	local ang = Attack.angleto(0, target)
	local k = 0.9
	function select(c)
		if Attack.cell_present(c) and (Attack.act_enemy(c) or Attack.act_ally(c)) then
			func(c)
		end
	end
	for n=0,Attack.cell_count()-1 do
		local i = Attack.cell_get(n)
		local ang2 = Attack.angleto(0,i)
		local d = Attack.cell_mdist(0,i)
		local gamma = math.abs(ang - ang2)
		if gamma < 1 then
			if d*math.sin(gamma) < k
			and not Attack.act_equal(0,i)
			and Attack.cell_dist(0,i) < 4 then
				select(i)
			end
		end
	end
	return true
end

function gamma_ray_filter(cell, present)

	if present then
		return true
	end
	return Attack.act_enemy(cell) and Attack.act_applicable(cell)
end

function gamma_ray_highlight(target)

	gamma_ray_enum_targets(target, function (c) Attack.cell_select(c, "avenemy") end)
	return true
end
--------
-- ***********************************************
-- * Gate of Netherworld
-- ***********************************************
--------
function special_gate_spells()

	Attack.log_label('null')
	local targets = {}
	for j=0,Attack.cell_count()-1 do
		local i = Attack.cell_get(j)
			if Attack.cell_dist(0,i) <=1
			and Attack.act_enemy(i) then
			table.insert(targets, i)
		end
	end
	if table.getn(targets) > 0 then
		local a = Attack.atom_spawn(0, 0, "magic_fireball", 5.5)
		local dmgts = Attack.aseq_time(a, "x")
		for j=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(j)
			if Attack.cell_dist(0,i) <=1 then
				if Attack.act_takesdmg(i) then
					local power = Attack.val_restore(0,"power")
					local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
					local typedmg = Attack.get_custom_param("typedmg")
					local duration = Attack.get_custom_param("duration")
					local k = Attack.get_custom_param("k")
					local fire_res = Attack.act_get_res(i,"fire")
					Attack.atk_set_damage(typedmg,dmg_min*power,dmg_max*power)
					common_cell_apply_damage(i,dmgts)
					if not Attack.act_feature(i,"boss,pawn,magic_immunitet,fire_immunitet")
					and fire_res<80
					and Game.CurLocRand(1,100) <25 then
						effect_burn_attack(i,dmgts+.3,duration,false)
						if Attack.act_size(i)>1 then
							Attack.log(0.001,"add_blog_burn_2", "targets", ""..blog_side_unit(i,1))
						else
							Attack.log(0.001,"add_blog_burn_1", "target", ""..blog_side_unit(i,1))
						end
					end
					Attack.log_label("")
				end
			end
		end
	elseif table.getn(targets) == 0 then
		local a = Attack.atom_spawn(0,0,"effect_demonsummon")
		local dmgts = Attack.aseq_time(a, "x")
		local belligerent = tonumber(Attack.val_restore(0,"belligerent"))
		if belligerent == 1 then belligerent = 2 end
		local k = Game.CurLocRand(text_range_dec(Attack.get_custom_param("k")))
		local units = Attack.get_custom_param("units")
		local summon_unit = text_dec(units,Game.CurLocRand(1,text_par_count(units)))
		local unit_count = Attack.val_restore(0,"power")
		local summon_lead = tonumber(Attack.atom_getpar(summon_unit,"leadership"))
		local summon_count = math.floor(1000*unit_count/summon_lead*k/100)
		if summon_count < 1 then summon_count = 1 end
		local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
		for i=1,Attack.act_count()-1 do
			if Attack.act_enemy(i) then
				local d = Attack.cell_dist(0,i)
				if d < nearest_dist then
					nearest_dist = d;
					nearest_enemy = i;
				end
			end
		end
		if nearest_enemy ~= nil then
			ang_to_enemy = Attack.angleto(0,nearest_enemy)
		end
		Attack.act_spawn(0, belligerent, summon_unit, ang_to_enemy, summon_count)
		local target = Attack.get_caa(Attack.get_cell(0))
		Attack.act_apply_spell_begin(target, "ks_effect_temporary", 2, false)
		Attack.act_apply_spell_end()
		Attack.act_nodraw(target, true)
		Attack.act_fadeout(target, 0, dmgts, 1)
		Attack.act_animate(target, "happy", dmgts)
		Attack.act_nodraw(target, false, dmgts)
		Attack.resort(target)
		Attack.log(0.001,"add_blog_summon_units", "target",""..blog_side_unit(target,0),"name",""..blog_side_unit(0,1),"special",""..summon_count)
	end
	return true
end

function temporary_onremove(caa)

	local trap = cell_trap(Attack.get_cell(caa))
	if trap and (Attack.act_mt(caa) == 0 or Attack.act_mt(caa) == 2) then Attack.cell_set_trap(Attack.get_cell(caa), nil, 0) end
	if Attack.act_hp(caa) > 0 then Attack.act_kill(caa,false,false) end
	local t = Attack.aseq_time(caa)
	if t < 0 then t = 0 end
	local fade_time = .5
	Attack.act_fadeout(caa, t, t + fade_time)
	Attack.log(0.001,"add_blog_temporary","name",blog_side_unit(caa))
	Attack.act_remove(caa, t + fade_time + .01)
	return true
end

function special_gate_of_netherworld()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local duration = Attack.get_custom_param("duration")
	local power = tonumber(Attack.act_size(0))
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	if target~=nil then
		local gate = Attack.atom_spawn(target, dmgt, "gate_of_netherworld", 0)
		Attack.act_nodraw(gate, true)
		Attack.act_animate(gate, "appear", dmgt)
		Attack.act_nodraw(gate, false, dmgt)
		Attack.val_store(gate, "belligerent", Attack.act_belligerent(0))
		Attack.act_set_par(gate, "attack", math.floor(power*.2+15))
		Attack.val_store(gate, "power", power)
		Attack.val_store(gate, "time_last", duration+1)
		Attack.resort(gate)
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end

function calccells_gate_of_netherworld()

	if Attack.is_computer_move() then
		local owner,failcells,emcells = {},{},{}
		local targets1,targets2,targets3,targets4,targets5,targets6,targets7,targets8,targets9,targets10 = {},{},{},{},{},{},{},{},{},{}
		for k=1, Attack.act_count()-1 do
			if (Attack.act_name(k)=="gate_of_netherworld"
			or Attack.act_name(k)=="blood_rune") then
				table.insert(owner, k)
			end
			if Attack.act_feature(k,"pawn,boss")
			or Attack.act_ally(k) then
				table.insert(failcells, k)
			end
			if Attack.act_enemy(k) then
				table.insert(emcells, k)
			end
		end
		for k=0,Attack.cell_count()-1 do
			local calcount,count1,count2,count3,count4,count5,count6 = 0,0,0,0,0,0,0
			local cell = Attack.cell_get(k)
			for k,v in ipairs(owner) do
				if Attack.cell_dist(v,cell) <=3 then
					calcount = calcount + 1
				end
			end
			for l,w in ipairs(failcells) do
				if Attack.cell_dist(w,cell) <=1 then
					calcount = calcount + 1
				end
			end
			for m,x in ipairs(emcells) do
				if Attack.cell_dist(x,cell) <=6 then
					count1 = count1 + 1
				end
				if Attack.cell_dist(x,cell) <=5 then
					count2 = count2 + 1
				end
				if Attack.cell_dist(x,cell) <=4 then
					count3 = count3 + 1
				end
				if Attack.cell_dist(x,cell) <=3 then
					count4 = count4 + 1
				end
				if Attack.cell_dist(x,cell) <=2 then
					count5 = count5 + 1
				end
			end
			if Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell) then
				if count1 == 0 and calcount == 0 then
					table.insert(targets1, cell)
				end
				if count2 == 0 and calcount == 0 then
					table.insert(targets2, cell)
				end
				if count3 == 0 and calcount == 0 then
					table.insert(targets3, cell)
				end
				if count4 == 0 and calcount == 0 then
					table.insert(targets4, cell)
				end
				if count5 == 0 and calcount == 0 then
					table.insert(targets5, cell)
				end
			end
			if Attack.act_enemy(cell) then
				count6 = count6 + 1
				for dir=0,5 do
					local d = Attack.cell_adjacent(cell, dir)
					if Attack.act_ally(d) then
						count6 = -5
					elseif Attack.act_enemy(d) then
						count6 = count6 + 1
					end
				end
				if count6 >= 7 then
					table.insert(targets6, cell)
				elseif count6 >= 6 then
					table.insert(targets7, cell)
				elseif count6 >= 5 then
					table.insert(targets8, cell)
				elseif count6 >= 4 then
					table.insert(targets9, cell)
				elseif count6 >= 3 then
					table.insert(targets10, cell)
				end
			elseif (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
				for dir=0,5 do
					local d = Attack.cell_adjacent(cell, dir)
					if Attack.act_ally(d) then
						count6 = -5
					elseif Attack.act_enemy(d) then
						count6 = count6 + 1
					end
				end
				if count6 >= 7 then
					table.insert(targets6, cell)
				elseif count6 >= 6 then
					table.insert(targets7, cell)
				elseif count6 >= 5 then
					table.insert(targets8, cell)
				elseif count6 >= 4 then
					table.insert(targets9, cell)
				elseif count6 >= 3 then
					table.insert(targets10, cell)
				end
			end
		end
		if table.getn(targets1) > 0 then
			for k,v in ipairs(targets1) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets2) > 0 then
			for k,v in ipairs(targets2) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets3) > 0 then
			for k,v in ipairs(targets3) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets4) > 0 then
			for k,v in ipairs(targets4) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets5) > 0 then
			for k,v in ipairs(targets5) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets6) > 0 then
			for k,v in ipairs(targets6) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets7) > 0 then
			for k,v in ipairs(targets7) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets8) > 0 then
			for k,v in ipairs(targets8) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets9) > 0 then
			for k,v in ipairs(targets8) do
				Attack.marktarget(v)
			end
		elseif table.getn(targets10) > 0 then
			for k,v in ipairs(targets8) do
				Attack.marktarget(v)
			end
		end
	else
		local owner,pawn,allies = {},{},{}
		local effect,effect2 = {},{}
		for k=1, Attack.act_count()-1 do
			if (Attack.act_name(k)=="gate_of_netherworld"
			or Attack.act_name(k)=="blood_rune") then
				table.insert(owner, k)
			end
			if Attack.act_feature(k,"pawn,boss") then
				table.insert(pawn, k)
			end
			if Attack.act_ally(k) then
				table.insert(allies, k)
			end
		end
		for c=0,Attack.cell_count()-1 do
			local count = 0
			local i = Attack.cell_get(c)
			for k,v in ipairs(owner) do
				if Attack.cell_dist(v,i) <=3 then
					count = count + 1
				end
			end
			for l,w in ipairs(pawn) do
				if Attack.cell_dist(w,i) <=1 then
					count = count + 1
				end
			end
			for m,x in ipairs(allies) do
				if Attack.cell_dist(x,i) <=1 then
					count = count + 1
				end
			end
			if count == 0
			and (Attack.act_enemy(i) or (Attack.cell_is_empty(i) and Attack.cell_is_pass(i))) then
				table.insert(effect, i)
			end
		end
		if table.getn(effect) > 0 then
			for k,v in ipairs(effect) do
				Attack.marktarget(v)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Sorrow
-- ***********************************************
--------
function special_sorrow()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local duration = tonumber(Attack.get_custom_param("duration"))
	if (target ~= nil) then

		if (Attack.act_ally(target)
		or Attack.act_enemy(target))
		and not Attack.act_feature(target,"golem,mech,pawn,boss") then

			local hitback = Attack.act_get_par(target, "hitback")
			if hitback == nil then hitback = 0 end
			Attack.atom_spawn(target, dmgt, "effect_inferno_appear")
			if Attack.act_is_spell(target, "effect_sorrow3") then

				Attack.act_del_spell(target, "effect_sorrow3")
				Attack.act_apply_spell_begin(target, "effect_sorrow3", duration, false)
				Attack.act_apply_par_spell("hitback", -hitback, 0, 0, duration, false)
				Attack.act_apply_par_spell("defense", 0, -30, 0, duration, false)
				Attack.act_apply_res_spell("poison", -45, 0, 0, duration, false)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then
					Attack.log(0.001,"add_blog_sorrow3", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
				end

			elseif Attack.act_is_spell(target, "effect_sorrow2") then

				Attack.act_del_spell(target, "effect_sorrow2")
				Attack.act_apply_spell_begin(target, "effect_sorrow3", duration, false)
				Attack.act_apply_par_spell("hitback", -hitback, 0, 0, duration, false)
				Attack.act_apply_par_spell("defense", 0, -30, 0, duration, false)
				Attack.act_apply_res_spell("poison", -45, 0, 0, duration, false)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then
					Attack.log(0.001,"add_blog_sorrow3", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
				end

			elseif Attack.act_is_spell(target, "effect_sorrow") then

				Attack.act_del_spell(target, "effect_sorrow")
				Attack.act_apply_spell_begin(target, "effect_sorrow2", duration, false)
				Attack.act_apply_par_spell("hitback", -hitback, 0, 0, duration, false)
				Attack.act_apply_par_spell("defense", 0, -20, 0, duration, false)
				Attack.act_apply_res_spell("poison", -30, 0, 0, duration, false)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then
					Attack.log(0.001,"add_blog_sorrow2", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
				end
			else
				Attack.act_del_spell(target, "effect_sorrow")
				Attack.act_del_spell(target, "effect_sorrow2")
				Attack.act_del_spell(target, "effect_sorrow3")
				Attack.act_apply_spell_begin(target, "effect_sorrow", duration, false)
				Attack.act_apply_par_spell("hitback", -hitback, 0, 0, duration, false)
				Attack.act_apply_par_spell("defense", 0, -10, 0, duration, false)
				Attack.act_apply_res_spell("poison", -15, 0, 0, duration, false)
				Attack.act_apply_spell_end()

				if Attack.act_size(target)>1 then
					Attack.log(0.001,"add_blog_sorrow", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
				end
			end
		end
	end
	return true
end

function calccells_sorrow()

	if Attack.is_computer_move() then
		local ai1,cacount = {},{}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				end
			end
			if Attack.act_ally(ai)
			and Attack.act_name(ai)=="cabalist" then
				table.insert(cacount, ai)
			end
		end
		if table.getn(ai1) == 1 and table.getn(cacount) > 0 then
			local targets1,targets2  = {},{}
			for i=1, Attack.act_count()-1 do
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"golem,mech,pawn,boss")
				and not Attack.act_temporary(i)
				and not Attack.act_is_spell(i, "effect_sorrow3") then
					if (Attack.act_is_spell(i, "effect_sorrow") or Attack.act_is_spell(i, "effect_sorrow2")) then
						table.insert(targets1, i)
					end
					if Attack.act_is_spell(i, "effect_counterspell") then
						table.insert(targets2, i)
					end
				end
			end
			if table.getn(targets1) > 0 then
				for k,v in ipairs(targets1) do
					Attack.marktarget(v)
				end
			elseif table.getn(targets2) > 0 then
				for k,v in ipairs(targets2) do
					Attack.marktarget(v)
				end
			end
		elseif table.getn(ai1) == 1 then
			local targets1,targets2  = {},{}
			for i=1, Attack.act_count()-1 do
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"golem,mech,pawn,boss")
				and not Attack.act_temporary(i)
				and not Attack.act_is_spell(i, "effect_sorrow3") then
					if (Attack.act_is_spell(i, "effect_sorrow") or Attack.act_is_spell(i, "effect_sorrow2")) then
						table.insert(targets1, i)
					else
						table.insert(targets2, i)
					end
				end
			end
			if table.getn(targets1) > 0 then
				for k,v in ipairs(targets1) do
					Attack.marktarget(v)
				end
			elseif table.getn(targets2) > 0 then
				for k,v in ipairs(targets2) do
					Attack.marktarget(v)
				end
			end
		else
			local targets1,targets2,failunits  = {},{},{}
			for i=1, Attack.act_count()-1 do
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"golem,mech,pawn,boss")
				and not Attack.act_is_spell(i, "spell_phantom")
				and not Attack.act_is_spell(i, "ks_effect_temporary")
				and not Attack.act_is_spell(i, "ks_effect_temporary_ghost")
				and not Attack.act_is_spell(i, "effect_sorrow3") then
					if (Attack.act_is_spell(i, "effect_sorrow") or Attack.act_is_spell(i, "effect_sorrow2")) then
						table.insert(targets1, i)
					end
					if Attack.act_get_res(i,"poison") <=0 then
						table.insert(failunits, i)
					elseif Attack.act_get_res(i,"poison") > 0
					and not Attack.act_is_spell(i, "spell_divine_armor") then
						table.insert(targets2, i)
					end
				end
			end
			if table.getn(targets1) > 0 then
				for k,v in ipairs(targets1) do
					Attack.marktarget(v)
				end
			elseif table.getn(targets2) > 0 and table.getn(failunits) == 0 then
				for k,v in ipairs(targets2) do
					Attack.marktarget(v)
				end
			end
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if Attack.act_enemy(i)
			and not Attack.act_feature(i,"golem,mech,pawn,boss")
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Nether Warp
-- ***********************************************
--------
function special_nether_warp()

	local target = Attack.get_target()
	if (target ~= nil) then
		local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0
		for i=1,Attack.act_count()-1 do

			if Attack.act_enemy(i) then
				local d = Attack.cell_dist(0,i)

				if d < nearest_dist then
					nearest_dist = d;
					nearest_enemy = i;
				end
			end
		end
		if nearest_enemy ~= nil then
			ang_to_enemy = Attack.angleto(target,nearest_enemy)
		end
		if Attack.act_ally(target)
		or (Attack.act_enemy(target) and not Attack.act_feature(target,"pawn,boss")) then

			Attack.act_aseq(0, "telein")
			Attack.act_aseq(target, "telein")
			Attack.atom_spawn(0, 0, "hll_telein")
			Attack.atom_spawn(target, 0, "hll_telein")
			local t = Attack.aseq_time(0)
			Attack.act_aseq(0, "teleout")
			Attack.act_aseq(target, "teleout")
			Attack.atom_spawn(0, t, "hll_teleout")
			Attack.atom_spawn(target, t, "hll_teleout")
			Attack.act_teleport(0, target, t)
			Attack.log(0.001,"add_blog_nether_warp_unit","name",""..blog_side_unit(0,1),"target",""..blog_side_unit(target,0))
		elseif Attack.cell_is_empty(target) and Attack.cell_is_pass(target) then

			Attack.act_aseq(0, "telein")
			Attack.atom_spawn(0, 0, "hll_telein")
			local t = Attack.aseq_time(0)
			Attack.act_aseq(0, "teleout" )
			Attack.atom_spawn(target, t, "hll_teleout")
			Attack.act_teleport(0, target, t, ang_to_enemy)
			Attack.log(0.001,"add_blog_nether_warp_space","name",""..blog_side_unit(0,1))
		end
		features_gate_keeper()
	end
	return true
end

function calccells_nether_warp()

	if Attack.is_computer_move() then
		local enemies,enemies2 = {},{}
		local escape,escape2,escape3 = {},{},{}
		for c=1,Attack.act_count()-1 do
			if Attack.act_enemy(c) or Attack.act_feature(c,"boss") then
				table.insert(enemies, c)
			end
		end
		for c=0,Attack.cell_count()-1 do
			local esccount,esccount2,esccount3 = 0,0,0
			local cell = Attack.cell_get(c)
			for k,v in ipairs(enemies) do
				if Attack.cell_dist(v,cell) <=5 then
					esccount = esccount + 1
				end
				if Attack.cell_dist(v,cell) <=4 then
					esccount2 = esccount2 + 1
				end
				if Attack.cell_dist(v,cell) <=3 then
					esccount3 = esccount3 + 1
				end
			end
			if esccount == 0 and (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
				table.insert(escape, cell)
			elseif esccount2 == 0 and (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
				table.insert(escape2, cell)
			elseif esccount3 == 0 and (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)) then
				table.insert(escape3, cell)
			end
		end
		for k,v in ipairs(enemies) do
			if Attack.cell_dist(v,0) <= 2 then
				table.insert(enemies2, v)
			end
		end
		if table.getn(escape) > 0 and table.getn(enemies2) > 0 then
			for k,v in ipairs(escape) do
				Attack.marktarget(v)
			end
		elseif table.getn(escape2) > 0 and table.getn(enemies2) > 0 then
			for k,v in ipairs(escape2) do
				Attack.marktarget(v)
			end
		elseif table.getn(escape3) > 0 and table.getn(enemies2) > 0 then
			for k,v in ipairs(escape3) do
				Attack.marktarget(v)
			end
		end
	else
		for i=0,Attack.cell_count()-1 do
			local cell = Attack.cell_get(i)
			if (Attack.act_ally(cell)
			or (Attack.act_enemy(cell) and not Attack.act_feature(cell,"pawn,boss"))
			or (Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell)))
			and not Attack.act_equal(0, cell) then
				Attack.marktarget(cell,false)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Devour Magic
-- ***********************************************
--------
-- function special_devour_magic()
function effect_devour_magic_attack(target,pause,duration,level,power,except_this)

	--[[ local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local a = Attack.atom_spawn(target, dmgt, "effect_devour_magic")
	dmgt1=Attack.aseq_time(a, "x")
	local duration = tonumber(Attack.get_custom_param("duration"))
	local level = tonumber(Attack.get_custom_param("level"))
	local power = tonumber(Attack.get_custom_param("power")) ]]
	local count=0

	if pause==nil then
		local pause = tonumber(Logic.obj_par("effect_devour_magic","pause"))
	end

	if duration==nil then
		local duration = tonumber(Logic.obj_par("effect_devour_magic","duration"))
	end

	if level==nil then
		local level = tonumber(Logic.obj_par("effect_devour_magic","level"))
	end

	if target~=nil then

		if Attack.act_is_spell(target, "special_magic_shield")
		and not Attack.act_is_spell(0, "special_magic_shield") then

			count=count+1
			devour_magic_shield(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_divine_armor")
		and not Attack.act_is_spell(0, "spell_divine_armor") then

			count=count+1
			devour_divine_armor(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_stone_skin")
		and not Attack.act_is_spell(0, "spell_stone_skin") then

			count=count+1
			devour_stone_skin(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_pacifism")
		and not Attack.act_is_spell(0, "spell_pacifism") then

			count=count+1
			devour_pacifism(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_magic_source")
		and not Attack.act_is_spell(0, "spell_magic_source") then

			count=count+1
			devour_magic_source(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_angel_avenger")
		and not Attack.act_is_spell(0, "spell_angel_avenger") then

			count=count+1
			devour_angel_avenger(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_haste")
		and not Attack.act_is_spell(0, "spell_haste") then

			count=count+1
			devour_haste(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_reaction")
		and not Attack.act_is_spell(0, "spell_reaction") then

			count=count+1
			devour_reaction(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_bless")
		and not Attack.act_is_spell(0, "spell_bless") then

			count=count+1
			devour_bless(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_demon_slayer")
		and not Attack.act_is_spell(0, "spell_demon_slayer") then

			count=count+1
			devour_demon_slayer(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_dragon_slayer")
		and not Attack.act_is_spell(0, "spell_dragon_slayer") then

			count=count+1
			devour_dragon_slayer(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_fire_breath")
		and not Attack.act_is_spell(0, "spell_fire_breath") then

			count=count+1
			devour_fire_breath(target,0,duration,level)

		elseif Attack.act_is_spell(target, "special_holy_rage")
		and not Attack.act_is_spell(0, "special_holy_rage") then

			count=count+1
			devour_holy_rage(target,0,duration,level)

		elseif Attack.act_is_spell(target, "special_magic_shield") then

			count=count+1
			devour_magic_shield(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_divine_armor") then

			count=count+1
			devour_divine_armor(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_stone_skin") then

			count=count+1
			devour_stone_skin(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_pacifism") then

			count=count+1
			devour_pacifism(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_magic_source") then

			count=count+1
			devour_magic_source(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_angel_avenger") then

			count=count+1
			devour_angel_avenger(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_haste") then

			count=count+1
			devour_haste(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_reaction") then

			count=count+1
			devour_reaction(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_bless") then

			count=count+1
			devour_bless(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_demon_slayer") then

			count=count+1
			devour_demon_slayer(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_dragon_slayer") then

			count=count+1
			devour_dragon_slayer(target,0,duration,level)

		elseif Attack.act_is_spell(target, "spell_fire_breath") then

			count=count+1
			devour_fire_breath(target,0,duration,level)

		elseif Attack.act_is_spell(target, "special_holy_rage") then

			count=count+1
			devour_holy_rage(target,0,duration,level)
		else
			for i=0,Attack.act_spell_count(target)-1 do

				local spell_name = Attack.act_spell_name(target,i)
				local spell_type = Logic.obj_par(spell_name,"type")
				local type = "bonus"

				if spell_type==type
				and string.find(spell_name,"^totem_")==nil
				and string.find(spell_name,"^ks_effect_")==nil
				and spell_name ~= "spell_slime_glot"
				and spell_name ~= "spell_phantom"
				and spell_name ~= except_this then

					count=count+1
					Attack.act_del_spell(0, "effect_magic_force")
					Attack.act_del_spell(target, spell_name)
					Attack.act_apply_spell_begin( 0, "effect_magic_force", duration, false)
					Attack.act_apply_par_spell("moral", power, 0, 0, duration, false)
					Attack.act_apply_par_spell("initiative", 0, power, 0, duration, false)
					Attack.act_apply_par_spell("speed", 0, power, 0, duration, false)
					Attack.act_apply_spell_end()

					if Attack.act_size(target)>1 then

						Attack.log(0.001,"add_blog_devour_bonus_magic", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
					end
					break
				end
			end
		end
	end

	if count>0 then

		if pause~=nil then
			Attack.atom_spawn(0, pause+.5, "effect_hero_appear")
		else
			Attack.atom_spawn(0, dmgt+dmgt1+.5, "effect_hero_appear")
		end
	end
	return true
end

function calccells_devour_magic(except_this)

	for j=0,Attack.cell_count()-1 do

		local i = Attack.cell_get(j)
		for k=0,Attack.act_spell_count(i)-1 do

			local spell_name = Attack.act_spell_name(i,k)
			local type = "bonus"
			local spell_type = Logic.obj_par(spell_name,"type")

			if not Attack.act_equal(i, 0)
			and spell_type==type
			and string.find(spell_name,"^totem_")==nil
			and spell_name ~= except_this then

				if Attack.act_applicable(i) then
					Attack.marktarget(i)
				end
			end
		end
	end
	return true
end

function devour_magic_shield(target,pause,duration,level)

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0, "special_magic_shield")
		Attack.act_del_spell(target, "special_magic_shield")

		Attack.act_apply_spell_begin(0, "special_magic_shield", duration, false)
		Attack.act_posthitslave(0, "post_magic_shield", duration)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_magic_shield", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_divine_armor(target,pause,duration,level)

	local resistbonus = 20

	if level == nil then level=1 end
	if level == 2 then
		resistbonus = 25
	elseif level == 3 then
		resistbonus = 30
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		local curfire,firebase = Attack.act_get_res(0,"fire")
		local curphysical,physicalbase = Attack.act_get_res(0,"physical")
		local curmagic,magicbase = Attack.act_get_res(0,"magic")
		local curpoison,poisonbase = Attack.act_get_res(0,"poison")
		local bonfire = resistbonus
		local bonphysical = resistbonus
		local bonmagic = resistbonus
		local bonpoison = resistbonus

		if firebase<bonfire then
			bonfire = bonfire-firebase
		else
			bonfire = 0
		end

		if physicalbase<bonphysical then
			bonphysical = bonphysical-physicalbase
		else
			bonphysical = 0
		end

		if magicbase<bonmagic then
			bonmagic = bonmagic-magicbase
		else
			bonmagic = 0
		end

		if poisonbase<bonpoison then
			bonpoison = bonpoison-poisonbase
		else
			bonpoison = 0
		end

		Attack.act_del_spell(0, "spell_divine_armor")
		Attack.act_del_spell(target, "spell_divine_armor")

		Attack.act_apply_spell_begin( 0, "spell_divine_armor", duration, false)
		Attack.act_apply_res_spell( "fire", bonfire, 0, 0, duration, false)
		Attack.act_apply_res_spell( "physical", bonphysical, 0, 0, duration, false)
		Attack.act_apply_res_spell( "magic", bonmagic, 0, 0, duration, false)
		Attack.act_apply_res_spell( "poison", bonpoison, 0, 0, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_divine_armor", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end


function devour_stone_skin(target,pause,duration,level)

	local power,penalty = 20,1

	if level == nil then level=1 end
	if level == 2 then
		power = 30
	elseif level == 3 then
		power = 40
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0, "spell_stone_skin")
		Attack.act_del_spell(target, "spell_stone_skin")

		Attack.act_apply_spell_begin(0, "spell_stone_skin", duration, false)
		Attack.act_apply_res_spell( "physical", power, 0, 0, duration, false)
		Attack.act_apply_par_spell( "initiative", -penalty, 0, 0, duration, false)
		Attack.act_apply_par_spell( "defense", 0, 0, power, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_stone_skin", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_pacifism(target,pause,duration,level)

	local bonus,penalty = 30,30

	if level == nil then level=1 end
	if level == 2 then
		bonus = 40
	elseif level == 3 then
		bonus = 50
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		local dfire, mindfire = Attack.act_get_dmg_min(0, "fire")
		local dpoison, mindpoison = Attack.act_get_dmg_min(0, "poison")
		local dmagic, mindmagic = Attack.act_get_dmg_min(0, "magic")
		local dphysical, mindphysical = Attack.act_get_dmg_min(0, "physical")
		local dfire, maxdfire = Attack.act_get_dmg_max(0, "fire")
		local dpoison, maxdpoison = Attack.act_get_dmg_max(0, "poison")
		local dmagic, maxdmagic = Attack.act_get_dmg_max(0, "magic")
		local dphysical, maxdphysical = Attack.act_get_dmg_max(0, "physical")
		local bhealth, bhealth = Attack.act_get_par(0, "health")
		local hbonus = bhealth*bonus/100

		Attack.act_del_spell(0,"spell_pacifism")
		Attack.act_del_spell(target,"spell_pacifism")

		Attack.act_apply_spell_begin(0, "spell_pacifism", duration, false )
		Attack.act_apply_dmgmax_spell( "fire", -maxdfire*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmax_spell( "poison", -maxdpoison*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmax_spell( "magic", -maxdmagic*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmax_spell( "physical", -maxdphysical*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "fire", -mindfire*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "poison", -mindpoison*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "magic", -mindmagic*penalty/100, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "physical", -mindphysical*penalty/100, 0, 0, duration, false)
		Attack.act_apply_par_spell( "health", hbonus, 0, 0, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_pacifism", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_magic_source(target,pause,duration,level)

	local penalty = 5
	local defense, basedefense = Attack.act_get_par(0, "defense")

	if level == nil then level=1 end
	if level == 2 then
		penalty = 10
	elseif level == 3 then
		penalty = 15
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0, "spell_magic_source")
		Attack.act_del_spell(target, "spell_magic_source")

		Attack.act_apply_spell_begin( 0, "spell_magic_source", duration, false)
		Attack.act_apply_par_spell( "defense", penalty, 0, 0, duration, false)
		Attack.act_spell_param(0, "spell_magic_source", "heroname", Attack.hero_name())
		Attack.act_posthitslave(0, "post_spell_mana_source" ,duration, tostring(level))
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_magic_source", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_angel_avenger(target,pause,duration,level)

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		local min_dmg, max_dmg = pwr_angel_avenger(level)

		Attack.act_del_spell(0, "spell_angel_avenger")
		Attack.act_del_spell(target, "spell_angel_avenger")

		Attack.act_apply_spell_begin(0, "spell_angel_avenger", duration, false)
		Attack.act_posthitslave(0, "post_spell_angel_avenger", duration)
		Attack.act_spell_param(0, "spell_angel_avenger", "damage", min_dmg.."-"..max_dmg)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_angel_avenger", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_haste(target,pause,duration,level)


	local speedbonus = 1

	if level == nil then level=1 end
	if level == 2 then
		speedbonus = 2
	elseif level == 3 then
		speedbonus = 3
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0,"spell_haste")
		Attack.act_del_spell(0,"spell_slow")
		Attack.act_del_spell(target,"spell_haste")
		Attack.act_del_spell(target,"spell_slow")

		Attack.act_apply_spell_begin(0, "spell_haste", duration, false )
		Attack.act_apply_par_spell( "speed", speedbonus, 0, 0, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_haste", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_reaction(target,pause,duration,level)

	local initiativebonus = 1

	if level == nil then level=1 end
	if level == 2 then
		initiativebonus = 2
	elseif level == 3 then
		initiativebonus = 3
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0,"spell_reaction")
		Attack.act_del_spell(target,"spell_reaction")

		Attack.act_apply_spell_begin(0, "spell_reaction", duration, false)
		Attack.act_apply_par_spell("initiative", initiativebonus, 0, 0, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_reaction", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_bless(target,pause,duration,level)

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0,"spell_weakness")
		Attack.act_del_spell(0,"spell_bless")
		Attack.act_del_spell(target,"spell_weakness")
		Attack.act_del_spell(target,"spell_bless")

		local mind, mindfire = Attack.act_get_dmg_min(0, "fire")
		local mind, mindpoison = Attack.act_get_dmg_min(0, "poison")
		local mind, mindmagic = Attack.act_get_dmg_min(0, "magic")
		local mind, mindphysical = Attack.act_get_dmg_min(0, "physical")
		local maxd, maxdfire = Attack.act_get_dmg_max(0, "fire")
		local maxd, maxdpoison = Attack.act_get_dmg_max(0, "poison")
		local maxd, maxdmagic = Attack.act_get_dmg_max(0, "magic")
		local maxd, maxdphysical = Attack.act_get_dmg_max(0, "physical")
		local bonfire = maxdfire - mindfire
		local bonpoison = maxdpoison - mindpoison
		local bonmagic = maxdmagic - mindmagic
		local bonphysical = maxdphysical - mindphysical

		Attack.act_apply_spell_begin( 0, "spell_bless", duration, false )
		Attack.act_apply_dmgmin_spell( "fire", bonfire, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "poison", bonpoison, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "magic", bonmagic, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "physical", bonphysical, 0, 0, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_bless", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_demon_slayer(target,pause,duration,level)

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0, "spell_demon_slayer")
		Attack.act_del_spell(target, "spell_demon_slayer")

		Attack.act_apply_spell_begin(0, "spell_demon_slayer", duration, false )
		Attack.act_posthitmaster(0, "post_spell_demon_slayer" ,duration,tostring(level))
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_demon_slayer", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_dragon_slayer(target,pause,duration,level)

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0, "spell_dragon_slayer")
		Attack.act_del_spell(target, "spell_dragon_slayer")

		Attack.act_apply_spell_begin(0, "spell_dragon_slayer", duration, false )
		Attack.act_posthitmaster(0, "post_spell_dragon_slayer" ,duration,tostring(level))
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_dragon_slayer", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_fire_breath(target,pause,duration,level)

	local power = 20

	if level == nil then level=1 end
	if level == 2 then
		power = 30
	elseif level == 3 then
		power = 40
	end

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0,"spell_fire_breath")
		Attack.act_del_spell(target,"spell_fire_breath")

		local mindfire = Attack.act_get_dmg_min(0, "fire")
		local mindpoison = Attack.act_get_dmg_min(0, "poison")
		local mindmagic = Attack.act_get_dmg_min(0, "magic")
		local mindphysical = Attack.act_get_dmg_min(0, "physical")
		local maxdfire = Attack.act_get_dmg_max(0, "fire")
		local maxdpoison = Attack.act_get_dmg_max(0, "poison")
		local maxdmagic = Attack.act_get_dmg_max(0, "magic")
		local maxdphysical = Attack.act_get_dmg_max(0, "physical")
		local max_dmg = (maxdfire + maxdpoison + maxdmagic + maxdphysical)*power/100
		local min_dmg = (mindfire + mindpoison + mindmagic + mindphysical)*power/100

		Attack.act_apply_spell_begin(0, "spell_fire_breath", duration, false )
		Attack.act_apply_dmgmax_spell( "fire", max_dmg, 0, 0, duration, false)
		Attack.act_apply_dmgmin_spell( "fire", min_dmg, 0, 0, duration, false)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_fire_breath", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end

function devour_holy_rage(target,pause,duration,level)

	if duration==nil then
		duration = 2
	end

	if target~=nil then

		Attack.act_del_spell(0,"special_holy_rage")
		Attack.act_del_spell(target,"special_holy_rage")

		Attack.act_apply_spell_begin(0, "special_holy_rage", duration, false)
		Attack.act_posthitmaster(0, "features_holy_attack" ,duration)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_devour_holy_rage", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	return true
end
--------
-- ***********************************************
-- * Faith Shield
-- **********************************************
--------
function special_faith_shield()

	local nearest_dist, nearest_enemy, ang_to_enemy = 10e10, nil, 0

	for k=1,Attack.act_count()-1 do

		if Attack.act_enemy(k) then
			local d = Attack.cell_dist(0,k)

			if d < nearest_dist then nearest_dist = d; nearest_enemy = k; end
		end
	end

	if nearest_enemy ~= nil then ang_to_enemy = nearest_enemy end
	local target = Attack.get_target()
	Attack.aseq_rotate(0, ang_to_enemy, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	local duration = tonumber(Attack.get_custom_param("duration"))
	local count = tonumber(Attack.act_size(target))
	local shield_hp = tonumber(Attack.get_custom_param("health"))
	shield_hp = shield_hp*count
	Attack.act_del_spell(target,"ks_effect_faith_shield")
	Attack.act_del_spell(target,"effect_poison")
	Attack.act_del_spell(target,"effect_burn")
	Attack.act_del_spell(target,"feat_bleeding")
	Attack.act_apply_spell_begin( target, "ks_effect_faith_shield", duration, false )
	Attack.act_posthitslave(target, "post_special_faith_shield", duration)
	Attack.val_store(0,"shield_hp",shield_hp)
	Attack.act_apply_spell_end()
	Attack.atom_spawn(target, dmgt, "effect_s_protection")

	if Attack.act_size(target)>1 then

		Attack.log(0.001,"add_blog_faith_shield", "name",""..blog_side_unit(target,1),"special",""..shield_hp)
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true

end

function calccells_self()

	if Attack.is_computer_move() then
		if not Attack.act_is_spell(0, "ks_effect_faith_shield") then
			Attack.marktarget(0)
		end
	elseif Attack.act_applicable(0) then
		Attack.marktarget(0)
	end
	return true
end
--------
-- ***********************************************
-- * Soul Link
-- **********************************************
--------
function special_soul_link()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "special")
	local dmgt = Attack.aseq_time(0, "x")
	local duration
	local mana = Attack.val_restore(0,"mana")
	local mana_used = tonumber(Attack.get_custom_param("mana_used"))
	if mana==nil then mana = 0 end
	if (target ~= nil) then

		Attack.atom_spawn(target, dmgt-.4, "magic_phantom")
		Attack.atom_spawn(0, dmgt, "magic_phantom")
		local master_id = Attack.act_uid(Attack.get_caa(0))
		local servant_id = Attack.val_restore(0,"servant_id")
		if servant_id~=0 and servant_id~="1111111" then

			local act = find_unit_by_uid(tonumber(servant_id))
			if act~= nil then

				Attack.act_del_spell(0, "ks_effect_soul_link_master" )
				Attack.act_del_spell(act, "ks_effect_soul_link_servant" )
				Attack.act_posthitslave(0,"post_master_soul_link",0)
				Attack.act_posthitslave(act,"post_servant_soul_link",0)
			end
		end

		servant_id = Attack.act_uid(Attack.get_caa(target))
		Attack.val_store(target,"master_id",master_id)
		Attack.val_store(0,"servant_id",servant_id)

		if Attack.act_is_spell(target, "effect_charm") then

			duration = tonumber(Attack.get_custom_param("duration"))
			Attack.act_apply_spell_begin(0, "ks_effect_soul_link_master", duration, false)
			Attack.act_apply_spell_begin(target, "ks_effect_soul_link_servant", duration, false)
			Attack.act_apply_spell_begin(target, "effect_charm", duration, false)
			Attack.act_posthitslave(0,"post_master_soul_link",duration)
			Attack.act_posthitslave(target,"post_servant_soul_link",duration)
  			Attack.act_apply_spell_end()
		else
			duration = 100
			Attack.act_apply_spell_begin(0, "ks_effect_soul_link_master", -duration, false)
			Attack.act_apply_spell_begin(target, "ks_effect_soul_link_servant", -duration, false)
			Attack.act_posthitslave(0,"post_master_soul_link",duration)
			Attack.act_posthitslave(target,"post_servant_soul_link",duration)
  			Attack.act_apply_spell_end()
		end

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_soul_link", "target",""..blog_side_unit(target,1),"name",""..blog_side_unit(0,0))
		end
	end
	mana = mana - mana_used
	if mana < 0 then mana = 0 end
	Attack.val_store(0,"mana",mana)
	return true
end

function calccells_soul_link()

	if Attack.is_computer_move() then
		if not Attack.act_is_spell(0, "ks_effect_soul_link_master") then
			local target = nil
			local hpoutput = nil
			for k=1,Attack.act_count()-1 do
			        if Attack.act_belligerent(k)
				and Attack.act_feature(k,"humanoid")
				and not (Attack.act_equal(k, 0)
				or Attack.act_temporary(k))
				and not Attack.act_is_spell(k, "spell_hypnosis")
				and not Attack.act_is_spell(k, "ks_effect_soul_link_servant")
				and Attack.act_applicable(k) then
					local hpinput = Attack.act_totalhp(k)
					if hpoutput == nil or hpinput > hpoutput then
						hpoutput = hpinput;
						target = k
					end
				end
			end
			if target ~= nil then
				Attack.marktarget(target)
			end
		end
	else
		local n = Attack.cell_count()
		for i=0,n-1 do

			local cell = Attack.cell_get(i)

			if Attack.act_belligerent(cell)  
			and Attack.act_feature(cell,"humanoid")
			and not (Attack.act_equal(cell, 0)
			or Attack.act_temporary(cell))
			and not Attack.act_is_spell(cell, "spell_hypnosis")
			and not Attack.act_is_spell(cell, "ks_effect_soul_link_servant")
			and Attack.act_applicable(cell) then

				Attack.marktarget(cell)
			end
		end
	end
	return true
end

function post_lifedrain_attack(damage,addrage,attacker,receiver,minmax)

	if (minmax==0) and damage>0
	and not (Attack.act_feature(receiver,"golem,mech,undead,pawn,boss") or Attack.act_name(receiver)=="griffin_spirit")
	and (Attack.atk_name() == "moveattack"
	or Attack.atk_class() == "moveattack") then

		local drain = damage
		local k = 25
		local max =  tonumber(Attack.act_totalhp(receiver))
		if max < drain then drain = max end
		drain = math.floor(drain*k/100)
		local count = AU.unitcount(attacker)
		local resr = math.floor(drain/AU.health(attacker))
		local heal = drain-resr*AU.health(attacker)
		Attack.act_size(attacker, count + resr)
		Attack.act_cure(attacker, heal, 1)
    		Attack.atom_spawn(attacker, .3, "effect_total_cure")

		if resr > 0 then
			Attack.log(0.001,"add_blog_lifedrain_resr", "target",""..blog_side_unit(receiver,0),"name",""..blog_side_unit(attacker,1), "special",""..heal_unit, "special2",""..resr)
		else
			Attack.log(0.001,"add_blog_lifedrain_cure", "target",""..blog_side_unit(receiver,0),"name",""..blog_side_unit(attacker,1), "special",""..heal)
		end
	end
	return damage,addrage
end
--------
-- ***********************************************
-- * Counterspell
-- **********************************************
--------
function special_counterspell()

	local target = Attack.get_target()
	Attack.aseq_rotate(0, target, "cast")
	local dmgt = Attack.aseq_time(0, "x")
	local duration = tonumber(Attack.get_custom_param("duration"))
	if (target ~= nil) then

		local cstgt_id = Attack.val_restore(0,"cstgt_id")
		if cstgt_id~=0 and csid~="1111111" then

			local act = find_unit_by_uid(tonumber(cstgt_id))
			if act~= nil then
				Attack.act_del_spell(act, "effect_counterspell" )
			end
		end

		cstgt_id = Attack.act_uid(Attack.get_caa(target))
		Attack.atom_spawn(target, dmgt, "effect_execution")
		takeoff_spells(target, "bonus")
		Attack.act_apply_spell_begin(target, "effect_counterspell", duration, false)
		Attack.val_store(0,"cstgt_id",cstgt_id)
		Attack.act_apply_spell_end()

		if Attack.act_size(target)>1 then

			Attack.log(0.001,"add_blog_counterspell", "target",""..blog_side_unit(target,1))
		end
	end
	return true
end

function calccells_counterspell()
	if Attack.is_computer_move() then
		local ai1,buffcount,targets = {},{},{}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				end
			end
		end
		if table.getn(ai1) == 1 then
			for i=1, Attack.act_count()-1 do
				if Attack.act_enemy(i)
				and not Attack.act_is_spell(i,"effect_counterspell")
				and not Attack.act_feature(i,"pawn,boss,magic_immunitet") then
					table.insert(targets, i)
				end
			end
		else
			for i=1, Attack.act_count()-1 do
				if Attack.act_enemy(i)
				and not Attack.act_feature(i,"pawn,boss,magic_immunitet") then
					for k=0,Attack.act_spell_count(i)-1 do
						local spell_name = Attack.act_spell_name(i,k)
						local spell_type = Logic.obj_par(spell_name,"type")
						if (spell_type=="bonus" or spell_type=="penalty")
						and string.find(spell_name,"^totem_")==nil
						and string.find(spell_name,"^ks_effect_")==nil
						and spell_name ~= "spell_slime_glot"
						and spell_name ~= "spell_phantom"
						and spell_name ~= "effect_counterspell" then
							table.insert(buffcount, spell_name)
							break
						end
					end
					if Attack.act_spell_count(i) >=2 and table.getn(buffcount) > 0 then
						table.insert(targets, i)
						for k,v in pairs(buffcount) do
							table.remove(buffcount)
						end
					end
				end
			end
		end
		if table.getn(targets) > 0 then
			for k,v in ipairs(targets) do
				Attack.marktarget(v)
			end
		end
	else
		for c=0,Attack.cell_count()-1 do
			local i = Attack.cell_get(c)
			if Attack.act_enemy(i)
			and not Attack.act_feature(i,"pawn,boss,magic_immunitet")
			and Attack.act_applicable(i) then
				Attack.marktarget(i)
			end
		end
	end
	return true
end
--------
-- ***********************************************
-- * Mass Target for Computer
-- ***********************************************
--------
function get_target_mass7_for_comp()
	local target
	local t1,t2,t3,t4,t5,t6,t7 = {},{},{},{},{},{},{}
	for k=0,Attack.cell_count()-1 do
		local count = 0
		local cell = Attack.cell_get(k)
		if Attack.act_enemy(cell) then
			count = count + 1
			for dir=0,5 do
				local d = Attack.cell_adjacent(cell, dir)
				if Attack.act_ally(d) then
					count = -8
				elseif Attack.act_enemy(d) then
					count = count + 1
				end
			end
			if count >= 7 then
				table.insert(t1, cell)
			elseif count >= 6 then
				table.insert(t2, cell)
			elseif count >= 5 then
				table.insert(t3, cell)
			elseif count >= 4 then
				table.insert(t4, cell)
			elseif count >= 3 then
				table.insert(t5, cell)
			elseif count >= 2 then
				table.insert(t6, cell)
			elseif count >= 1 then
				table.insert(t7, cell)
			end
		elseif Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell) then
			for dir=0,5 do
				local d = Attack.cell_adjacent(cell, dir)
				if Attack.act_ally(d) then
					count = -8
				elseif Attack.act_enemy(d) then
					count = count + 1
				end
			end
			if count >= 7 then
				table.insert(t1, cell)
			elseif count >= 6 then
				table.insert(t2, cell)
			elseif count >= 5 then
				table.insert(t3, cell)
			elseif count >= 4 then
				table.insert(t4, cell)
			elseif count >= 3 then
				table.insert(t5, cell)
			elseif count >= 2 then
				table.insert(t6, cell)
			elseif count >= 1 then
				table.insert(t7, cell)
			end
		end
	end
	if table.getn(t1) > 0 then
		target = t1[Game.CurLocRand(1,table.getn(t1))]
	elseif table.getn(t2) > 0 then
		target = t2[Game.CurLocRand(1,table.getn(t2))]
	elseif table.getn(t3) > 0 then
		target = t3[Game.CurLocRand(1,table.getn(t3))]
	elseif table.getn(t4) > 0 then
		target = t4[Game.CurLocRand(1,table.getn(t4))]
	elseif table.getn(t5) > 0 then
		target = t5[Game.CurLocRand(1,table.getn(t5))]
	elseif table.getn(t6) > 0 then
		target = t6[Game.CurLocRand(1,table.getn(t6))]
	elseif table.getn(t7) > 0 then
		target = t7[Game.CurLocRand(1,table.getn(t7))]
	else
		target = Attack.get_target()
	end
	return target
end

function calccells_ks_mass_all()

	if Attack.is_computer_move() then
		local ai1,ai2 = {},{}
		for ai=1,Attack.act_count()-1 do
			if Attack.act_enemy(ai)
			and not Attack.act_feature(ai,"pawn,boss") then
				if not Attack.act_temporary(ai) then
					table.insert(ai1, ai)
				elseif Attack.act_temporary(ai) then
					table.insert(ai2, ai)
				end
			end
		end
		local bel = Attack.act_belligerent(0)
		if bel == 0 or bel == 4 then
			if table.getn(ai1) == 1 and table.getn(ai2) > 0 then return ture end
		end
		local t1,t2,t3,t4,t5 = {},{},{},{},{}
		for k=0,Attack.cell_count()-1 do
			local count = 0
			local cell = Attack.cell_get(k)
			if Attack.act_enemy(cell) then
				count = count + 1
				for dir=0,5 do
					local d = Attack.cell_adjacent(cell, dir)
					if Attack.act_ally(d) then
						count = -8
					elseif Attack.act_enemy(d) then
						count = count + 1
					end
				end
				if count >= 7 then
					table.insert(t1, cell)
				elseif count >= 6 then
					table.insert(t2, cell)
				elseif count >= 5 then
					table.insert(t3, cell)
				elseif count >= 4 then
					table.insert(t4, cell)
				elseif count >= 3 then
					table.insert(t5, cell)
				end
			elseif Attack.cell_is_empty(cell) and Attack.cell_is_pass(cell) then
				for dir=0,5 do
					local d = Attack.cell_adjacent(cell, dir)
					if Attack.act_ally(d) then
						count = -8
					elseif Attack.act_enemy(d) then
						count = count + 1
					end
				end
				if count >= 7 then
					table.insert(t1, cell)
				elseif count >= 6 then
					table.insert(t2, cell)
				elseif count >= 5 then
					table.insert(t3, cell)
				elseif count >= 4 then
					table.insert(t4, cell)
				elseif count >= 3 then
					table.insert(t5, cell)
				end
			end
		end
		if table.getn(t1) > 0 then
			local tgt = ai_hp_count_mass7(t1)
			Attack.marktarget(tgt)
		elseif table.getn(t2) > 0 then
			local tgt = ai_hp_count_mass7(t2)
			Attack.marktarget(tgt)
		elseif table.getn(t3) > 0 then
			local tgt = ai_hp_count_mass7(t3)
			Attack.marktarget(tgt)
		elseif table.getn(t4) > 0 then
			local tgt = ai_hp_count_mass7(t4)
			Attack.marktarget(tgt)
		elseif table.getn(t5) > 0 then
			local tgt = ai_hp_count_mass7(t5)
			Attack.marktarget(tgt)
		end
	else
		Attack.multiselect(7)
		for i=0,Attack.cell_count()-1 do
			local cell = Attack.cell_get(i)
			if Attack.cell_is_pass(cell) or Attack.get_caa(cell) ~= nil then
				Attack.marktarget(cell, false)
			end
		end
	end
	return true
end

function ai_hp_count_mass7(target)

	local tgt = nil
	local tgtcount,hpoutput = nil,nil
	local tohpcount = 0
	for k,v in ipairs(target) do
		if Attack.act_enemy(v) then
			local hpinput = Attack.act_totalhp(v)
			tohpcount = tohpcount + hpinput
			for dir = 0,5 do
				local d = Attack.cell_adjacent(v, dir)
				if Attack.act_enemy(d) then
					local hpinput2 = Attack.act_totalhp(d)
					tohpcount = tohpcount + hpinput2
				end
			end
		elseif Attack.cell_is_empty(v) and Attack.cell_is_pass(v) then
			local hpinput = Attack.act_totalhp(v)
			for dir = 0,5 do
				local d = Attack.cell_adjacent(v, dir)
				if Attack.act_enemy(d) then
					local hpinput2 = Attack.act_totalhp(d)
					tohpcount = tohpcount + hpinput2
				end
			end
		end
		if hpoutput == nil or tohpcount < hpoutput then
			hpoutput = tohpcount;
			tgtcount = v
		end
	end
	if tgtcount ~= nil then
		tgt = tgtcount
	end
	return tgt
end

function ai_hp_count(target)

	local tgt = nil
	local tgtcount,hpoutput = nil,nil
	for k,v in ipairs(target) do
		local hpinput = Attack.act_totalhp(v)
		if hpoutput == nil or hpinput < hpoutput then
			hpoutput = hpinput;
			tgtcount = v
		end
	end
	if tgtcount ~= nil then
		tgt = tgtcount
	end
	return tgt
end

function ai_lv_count(target)

	local tgt = nil
	local tgtcount,lvoutput = nil,nil
	for k,v in ipairs(target) do
		local lvinput = Attack.act_level(v)
		if lvoutput == nil or lvinput < lvoutput then
			lvoutput = lvinput;
			tgtcount = v
		end
	end
	if tgtcount ~= nil then
		tgt = tgtcount
	end
	return tgt
end
--------
-- ***********************************************
-- * Patch
-- ***********************************************
--------
function takeoff_spells(target, type, check_only, except_this)

	local spells_to_delete={}
	for i=0,Attack.act_spell_count(target)-1 do

		local spell_name=Attack.act_spell_name(target,i)
		local spell_type=Logic.obj_par(spell_name,"type")
		if spell_type==type
		and string.find(spell_name,"^totem_")==nil
		and string.find(spell_name,"^ks_effect_")==nil
		and spell_name ~= "spell_slime_glot"
		and spell_name ~= "spell_phantom"
		and spell_name ~= except_this then
			table.insert(spells_to_delete, spell_name)
		end
	end
	if check_only then return table.getn(spells_to_delete) > 0 end
	for k,v in ipairs(spells_to_delete) do
		Attack.act_del_spell(target,v)
	end
	return table.getn(spells_to_delete) > 0
end

function ks_dispell(target)

	local spell_remove={}
	for i=0,Attack.act_spell_count(target)-1 do

		local spell_name=Attack.act_spell_name(target,i)
		if string.find(spell_name,"^totem_")==nil
		and string.find(spell_name,"^ks_effect_")==nil
		and spell_name ~= "spell_slime_glot"
		and spell_name ~= "spell_phantom" then
			table.insert(spell_remove, spell_name)
		end
	end
	for k,v in ipairs(spell_remove) do
		Attack.act_del_spell(target,v)
	end
	return table.getn(spell_remove) > 0
end

function spell_dispell_attack()

	local level=Obj.spell_level()
	if level==0 then level=1 end
	local target = Attack.get_target()
	local mode = text_dec(Logic.obj_par("spell_dispell","spell"),level)
	if (target ~= nil) then

		if Attack.act_is_spell(target, "effect_counterspell") then
			Attack.atom_spawn(target, 0, "magic_dispel" )
			Attack.log(0.001,"add_blog_remove_debuff_fail", "name",""..blog_side_unit(target,1))
		else
			if mode == "all" then
				ks_dispell(target)
			else
				local type
				if Attack.act_ally(target) then
					type = "penalty"
				else
					type = "bonus"
				end

				if (Attack.act_is_spell(target, "spell_hypnosis") or Attack.act_is_spell(target, "effect_charm"))
				and Logic.obj_par("spell_hypnosis","type")==type then
					Attack.act_del_spell(target, "spell_hypnosis")
					Attack.act_del_spell(target, "effect_charm")
					if Attack.act_ally(target) then
						type = "penalty"
					else
						type = "bonus"
					end
				end
				takeoff_spells(target, type)
			end
			Attack.atom_spawn(target, 0, "magic_dispel" )
		end
	end
	return true
end

function special_dispell()

	local target = Attack.get_target()
	Attack.act_aseq( 0, "special" )
	local dmgts = Attack.aseq_time(0, "x")

	if (target ~= nil) then
		if Attack.act_is_spell(target, "effect_counterspell") then
			Attack.atom_spawn(target, dmgts, "magic_dispel")
			Attack.log(0.001,"add_blog_remove_debuff_fail", "name",""..blog_side_unit(target,1))
		else
			ks_dispell(target)
			Attack.atom_spawn(target, dmgts, "magic_dispel")
		end
	end
	return true
end

function griffin_clear_effect()

	local spell_remove={}
	for i=0,Attack.act_spell_count(0)-1 do
		local spell_name=Attack.act_spell_name(0,i)
		if string.find(spell_name,"^totem_")==nil
		and string.find(spell_name,"^ks_effect_")==nil
		and spell_name ~= "spell_slime_glot"
		and spell_name ~= "mod_pcbun_lvlup"
		and spell_name ~= "chp_expirience"
		and spell_name ~= "spell_phantom" then
			table.insert(spell_remove, spell_name)
		end
	end
	if table.getn(spell_remove) > 0 then
		ks_dispell(0)
		Attack.act_aseq(0, "clear")	
		Attack.aseq_timeshift(0,1)
		Attack.log("add_blog_clear_bonus","name",blog_side_unit(0))
	end
	return true
end

function total_dmg_hint()
	local dmg_min,dmg_max = text_range_dec(Attack.get_custom_param("damage"))
	local power = tonumber(Attack.act_size(0))
	text = tostring(dmg_min*power).."-"..tostring(dmg_max*power)
	return text
end

function double_type_dmg_hint()
	local dmg_min1,dmg_max1 = text_range_dec(Attack.get_custom_param("damage1"))
	local dmg_min2,dmg_max2 = text_range_dec(Attack.get_custom_param("damage2"))
	text = tostring(dmg_min1+dmg_min2).."-"..tostring(dmg_max1+dmg_max2)
	return text
end
--------